50 lines
2.1 KiB
SQL
50 lines
2.1 KiB
SQL
-- 03-migrate-phash-bigint-to-vector.sql
|
||
-- 兼容旧库:phash 早期以 bigint 存储 64-bit dHash 指纹(uint64),现模型改为 vector(64)。
|
||
-- pgvector 不支持 bigint -> vector 直接转换,需逐位拆成 0/1 向量(位 i -> 第 i 维,
|
||
-- 与 Go 侧 phash.ToVectorBits 完全一致,保证旧数据与新写入向量在同一语义空间可比)。
|
||
--
|
||
-- 用法(任选其一):
|
||
-- 1) 后端启动时由 AutoMigrate 自动执行(已内置,幂等,无需手动);
|
||
-- 2) 手动执行: psql "postgres://fashion:fashion_dev_2026@localhost:5432/fashion" -f 03-migrate-phash-bigint-to-vector.sql
|
||
--
|
||
-- 已为 vector/text 类型的列自动跳过;可重复执行。
|
||
|
||
DO $$
|
||
DECLARE
|
||
t text;
|
||
dt text;
|
||
BEGIN
|
||
FOR t IN
|
||
SELECT tablename FROM pg_tables
|
||
WHERE schemaname = 'public'
|
||
AND tablename IN ('brand_runway_images','brand_runway_draft_images','street_snap_images','street_snap_draft_images')
|
||
LOOP
|
||
SELECT data_type INTO dt
|
||
FROM information_schema.columns
|
||
WHERE table_schema = 'public' AND table_name = t AND column_name = 'phash';
|
||
|
||
IF dt = 'bigint' THEN
|
||
-- bigint 即 64-bit dHash 指纹;pgvector 不支持 bigint->vector 直接转换,且 ALTER ... USING 的
|
||
-- transform 表达式不允许子查询(0A000)。改用纯表达式:bigint::bit(64) 取 64 位模式(MSB 在左),
|
||
-- reverse 成 LSB 在左(与 phash.ToVectorBits 维度顺序一致:第 i 维 = bit i),插逗号后 text::vector(64)。
|
||
-- NULL 自然透传。
|
||
EXECUTE format($e$
|
||
ALTER TABLE %I ALTER COLUMN phash TYPE vector(64)
|
||
USING (
|
||
('[' ||
|
||
rtrim(regexp_replace(reverse(phash::bit(64)::text), '(.)', '\1,', 'g'), ',') ||
|
||
']')::vector(64)
|
||
)
|
||
$e$, t);
|
||
RAISE NOTICE 'migrated phash (bigint -> vector) on %', t;
|
||
ELSIF dt IN ('character varying','text') THEN
|
||
EXECUTE format($e$
|
||
ALTER TABLE %I ALTER COLUMN phash TYPE vector(64) USING phash::vector(64)
|
||
$e$, t);
|
||
RAISE NOTICE 'migrated phash (text -> vector) on %', t;
|
||
ELSE
|
||
RAISE NOTICE 'phash on % already type %, skipped', t, dt;
|
||
END IF;
|
||
END LOOP;
|
||
END $$;
|