四层同步必须对齐:数据库扩展类型需驱动注册、ORM动态反射、迁移工具显式声明、应用层手动处理序列化,任一环节缺失都会导致字段失效。
SQLAlchemy 中 MetaData.reflect() 为什么没更新新增字段
直接调用 metadata.reflect() 不会自动覆盖已存在的 table 对象,它只对尚未加载的表生效。如果你改了数据库表结构(比如加了 jsonb 字段),但模型类仍用旧的 table 定义,查询时就会报 keyerror 或忽略新列。
- 必须先清空
metadata.tables缓存,或新建MetaData实例再 reflect - 反射后需手动重建模型类的
__table__属性,不能依赖声明时的静态定义 - 注意:
autoload_with在Table(...)中只在首次创建时触发,后续改库不自动重载
Django 迁移后 models.JSONField 查询报 FieldError
Django 的 JSONField 在 PostgreSQL 上底层是 jsonb,但迁移文件生成后若手动改了数据库字段类型(比如从 text 改成 jsonb),Django ORM 并不会感知——它仍按旧字段类型解析,导致 filter(data__name="x") 报错。
- 确保迁移中显式指定
db_type="jsonb"(Django 4.2+ 可省略,但老版本需确认) - 执行
python manage.py makemigrations --empty手动补一个“绕过检测”的迁移,用RunPython调cursor.execute("ALTER COLUMN ... TYPE jsonb USING ...::jsonb") - 避免用
db_type混用:MySQL 的JSON和 PG 的jsonb行为差异大,跨库时字段逻辑要隔离
Go + GORM v2 处理 pgvector 向量字段同步失败
GORM 默认不识别 vector(1536) 这类扩展类型,即使数据库已建好字段,AutoMigrate 也会跳过或报 unknown type vector,更别说读写。
- 必须提前注册自定义类型:
gorm.RegisterDriver("postgres", gorm.Postgres{DataTypeMap: map[string]string{"vector": "vector"}}) - 字段声明要用指针+自定义 struct,例如
Embedding *pgvector.Vector `gorm:"type:vector(1536);not null"`,不能用[]float32直接映射 - 注意 pgvector 插件是否在目标 schema 启用:
CREATE EXTENSION IF NOT EXISTS vector SCHEMA public;,否则AutoMigrate会静默失败
Prisma 中 Json 和 Unsupported("jsonb") 怎么选
PostgreSQL 的 jsonb 字段在 Prisma Schema 里有两种写法:Json @db.Json 或 Json @db.Unsupported("jsonb")。前者由 Prisma 自动处理序列化,后者完全交由 driver 处理——但一旦选错,prisma migrate dev 就可能把字段类型来回改,甚至丢数据。
- 用
@db.Json:适合纯 JSON 内容,Prisma 保证读写一致性,但不支持jsonb_path_query等高级操作 - 用
@db.Unsupported("jsonb"):可配合$queryRaw调原生函数,但必须自己处理 Go/Node 层的序列化,且prisma generate后字段类型是any,无类型提示 - 迁移前务必检查
prisma db pull输出的字段类型,避免Json和Unsupported混用导致 schema drift
扩展类型不是加个字段就完事——数据库、ORM、驱动、迁移工具四层之间,只要有一层没对齐类型定义或生命周期管理,同步就会断在某个环节。最常被忽略的是:驱动层是否真正支持该类型,以及 ORM 是否在运行时重新拉取了元信息。










