Ensure pgvector extension in migrator + add pgvector diagnostic
The baseline schema needs the `vector` extension (memories.vision_embedding), but nothing created it on deploy — a fresh DB hit "could not access file vector" and migrations failed. - migrate.ts now runs CREATE EXTENSION IF NOT EXISTS vector (superuser) before applying migrations, with a clear error if the Postgres image lacks pgvector. - /api/debug-migration GET now reports pgvector status (binaryAvailable / installed) so the image/extension can be checked from the browser. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
deaa1810d7
commit
470df7fb9f
2 changed files with 37 additions and 1 deletions
|
|
@ -13,7 +13,19 @@ export async function GET() {
|
||||||
const circleTables = await sql.unsafe(
|
const circleTables = await sql.unsafe(
|
||||||
`SELECT tablename FROM pg_tables WHERE schemaname = 'public' AND (tablename LIKE 'circle%' OR tablename = 'post_reports') ORDER BY tablename`
|
`SELECT tablename FROM pg_tables WHERE schemaname = 'public' AND (tablename LIKE 'circle%' OR tablename = 'post_reports') ORDER BY tablename`
|
||||||
);
|
);
|
||||||
return NextResponse.json({ migrations, circleTables });
|
// pgvector status: is the binary available in this Postgres image, and is
|
||||||
|
// the extension actually created? (diagnoses "could not access file vector")
|
||||||
|
const vectorRows = await sql.unsafe(
|
||||||
|
`SELECT name, default_version, installed_version FROM pg_available_extensions WHERE name = 'vector'`
|
||||||
|
);
|
||||||
|
const v = vectorRows[0] as { default_version?: string; installed_version?: string } | undefined;
|
||||||
|
const pgvector = {
|
||||||
|
binaryAvailable: !!v, // false → wrong Postgres image (no pgvector)
|
||||||
|
installed: !!v?.installed_version, // false → needs CREATE EXTENSION vector
|
||||||
|
availableVersion: v?.default_version ?? null,
|
||||||
|
installedVersion: v?.installed_version ?? null,
|
||||||
|
};
|
||||||
|
return NextResponse.json({ migrations, circleTables, pgvector });
|
||||||
} catch (err: unknown) {
|
} catch (err: unknown) {
|
||||||
return NextResponse.json({ error: err instanceof Error ? err.message : String(err) });
|
return NextResponse.json({ error: err instanceof Error ? err.message : String(err) });
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,30 @@ async function main() {
|
||||||
const client = postgres(url, { max: 1 });
|
const client = postgres(url, { max: 1 });
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
// The baseline schema uses pgvector (memories.vision_embedding vector(1536)
|
||||||
|
// + ivfflat index), so the `vector` extension MUST exist before migrations
|
||||||
|
// run. We do it here — not in a migration file — because CREATE EXTENSION
|
||||||
|
// needs a superuser (this runner uses DATABASE_URL_SUPERUSER). Idempotent.
|
||||||
|
//
|
||||||
|
// This only succeeds if the Postgres image actually ships the pgvector
|
||||||
|
// binaries (e.g. the pgvector/pgvector image). A plain `postgres` image
|
||||||
|
// will fail here with "could not access file vector" — that's an infra
|
||||||
|
// problem (wrong DB image), and failing loud is correct.
|
||||||
|
console.log("[migrate] ensuring pgvector 'vector' extension...");
|
||||||
|
try {
|
||||||
|
await client`CREATE EXTENSION IF NOT EXISTS vector`;
|
||||||
|
console.log("[migrate] pgvector extension ready.");
|
||||||
|
} catch (extErr) {
|
||||||
|
console.error(
|
||||||
|
"[migrate] FAILED to create the pgvector 'vector' extension.\n" +
|
||||||
|
" → The Postgres image must include pgvector (use the pgvector/pgvector image,\n" +
|
||||||
|
" e.g. pgvector/pgvector:pg18 to match prod), and the migration connection\n" +
|
||||||
|
" (DATABASE_URL_SUPERUSER) must be a superuser.",
|
||||||
|
extErr
|
||||||
|
);
|
||||||
|
throw extErr;
|
||||||
|
}
|
||||||
|
|
||||||
console.log("[migrate] applying pending migrations...");
|
console.log("[migrate] applying pending migrations...");
|
||||||
await migrate(drizzle(client), { migrationsFolder: "./drizzle" });
|
await migrate(drizzle(client), { migrationsFolder: "./drizzle" });
|
||||||
console.log("[migrate] done — schema is up to date.");
|
console.log("[migrate] done — schema is up to date.");
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue