fix: repair pgvector migration to actually convert embedding column from text to vector(1536)
All checks were successful
Deploy to Production / Build and Deploy (push) Successful in 4s
All checks were successful
Deploy to Production / Build and Deploy (push) Successful in 4s
The original migration used a fragile add-copy-drop-rename pattern with _jsonb casts that silently failed, leaving the embedding column as text. Replace with a direct ALTER COLUMN TYPE ... USING embedding::vector(1536) that is fully idempotent and handles all partial states from previous failed attempts.
This commit is contained in:
@@ -1,48 +1,43 @@
|
||||
-- Phase 1: Enable pgvector extension
|
||||
CREATE EXTENSION IF NOT EXISTS vector;
|
||||
|
||||
-- Phase 2: Convert embedding column from text/JSON to vector(1536) if needed
|
||||
-- Phase 2: Convert embedding column from text to vector(1536)
|
||||
-- Idempotent: detects current column type and only converts when needed.
|
||||
-- Handles all partial states from previous failed migration attempts:
|
||||
-- A) embedding is text → direct ALTER COLUMN TYPE conversion
|
||||
-- B) embedding already vector → skip
|
||||
-- C) embedding missing, _vec_tmp exists → rename
|
||||
DO $$
|
||||
DECLARE
|
||||
_udt text;
|
||||
_vec_tmp_exists boolean;
|
||||
_emb_type text;
|
||||
_tmp_type text;
|
||||
BEGIN
|
||||
SELECT udt_name INTO _udt
|
||||
SELECT udt_name INTO _emb_type
|
||||
FROM information_schema.columns
|
||||
WHERE table_schema = 'public'
|
||||
AND table_name = 'NoteEmbedding'
|
||||
AND column_name = 'embedding';
|
||||
|
||||
IF _udt IS NOT NULL AND _udt != 'vector' THEN
|
||||
SELECT EXISTS (
|
||||
SELECT 1 FROM information_schema.columns
|
||||
WHERE table_schema = 'public'
|
||||
AND table_name = 'NoteEmbedding'
|
||||
AND column_name = '_vec_tmp'
|
||||
) INTO _vec_tmp_exists;
|
||||
IF _emb_type = 'vector' THEN
|
||||
RETURN;
|
||||
END IF;
|
||||
|
||||
IF NOT _vec_tmp_exists THEN
|
||||
ALTER TABLE "NoteEmbedding" ADD COLUMN "_vec_tmp" vector(1536);
|
||||
END IF;
|
||||
IF _emb_type IS NOT NULL THEN
|
||||
ALTER TABLE "NoteEmbedding" DROP COLUMN IF EXISTS "_vec_tmp";
|
||||
ALTER TABLE "NoteEmbedding"
|
||||
ALTER COLUMN "embedding" TYPE vector(1536)
|
||||
USING "embedding"::vector(1536);
|
||||
RETURN;
|
||||
END IF;
|
||||
|
||||
UPDATE "NoteEmbedding"
|
||||
SET "_vec_tmp" = ("embedding"::jsonb)::text::vector(1536)
|
||||
WHERE "embedding" IS NOT NULL
|
||||
AND "_vec_tmp" IS NULL;
|
||||
SELECT udt_name INTO _tmp_type
|
||||
FROM information_schema.columns
|
||||
WHERE table_schema = 'public'
|
||||
AND table_name = 'NoteEmbedding'
|
||||
AND column_name = '_vec_tmp';
|
||||
|
||||
ALTER TABLE "NoteEmbedding" DROP COLUMN "embedding";
|
||||
IF _tmp_type IS NOT NULL THEN
|
||||
ALTER TABLE "NoteEmbedding" RENAME COLUMN "_vec_tmp" TO "embedding";
|
||||
ELSIF _udt IS NULL THEN
|
||||
SELECT EXISTS (
|
||||
SELECT 1 FROM information_schema.columns
|
||||
WHERE table_schema = 'public'
|
||||
AND table_name = 'NoteEmbedding'
|
||||
AND column_name = '_vec_tmp'
|
||||
) INTO _vec_tmp_exists;
|
||||
|
||||
IF _vec_tmp_exists THEN
|
||||
ALTER TABLE "NoteEmbedding" RENAME COLUMN "_vec_tmp" TO "embedding";
|
||||
END IF;
|
||||
END IF;
|
||||
END $$;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user