Sync2 是 XORM 的自动迁移入口,仅支持检测并添加缺失字段,不修改已有字段类型、长度或删除冗余字段,需配合手动 SQL 处理生产环境字段变更。

Sync2 是 XORM 实际可用的自动迁移入口,但它不是“一键升级表结构”的魔法开关——它只做增量同步,且默认不修改已有字段类型或删除冗余字段。
为什么 Sync2 有时没反应?
常见现象:改了结构体字段类型(比如把 string 改成 sql.NullString),执行 engine.Sync2(new(User)) 后数据库表毫无变化。
- XORM 的同步逻辑是「检测缺失字段并添加」,不是「对比全量差异并修正」;它不会主动修改已存在字段的类型、长度或 NULL 约束
- 字段名映射依赖标签里的显式定义,如果漏写
xorm:"varchar(100)",XORM 会按默认规则推断(如string→text),导致与预期不符 - 若表已存在且字段名完全匹配,
Sync2不会报错也不做任何事——它安静得像没运行过 - 必须开启警告日志才能看到字段类型不一致、默认值缺失等提示:
engine.ShowWarn(true)
Sync2 和手动 SQL 迁移怎么选?
当你要改字段类型、重命名列、删字段或加 CHECK 约束时,Sync2 就不够用了。
-
Sync2适合:新项目初始化、新增字段、加索引、首次建表 - 手动 SQL 适合:生产环境字段变更(如
ALTER TABLE users MODIFY COLUMN name VARCHAR(255) NOT NULL)、跨类型转换(INT→BIGINT)、处理中文字段名(XORM 默认不支持反射中文变量名) - 混合用法更现实:用
Sync2快速对齐新增字段,再用engine.Exec()补充关键变更 - 注意 MySQL 的
ALGORITHM=INPLACE兼容性,避免大表锁死;PostgreSQL 对字段重命名需RENAME COLUMN单独执行
结构体字段名大小写与数据库兼容性
Go 结构体字段必须导出(首字母大写),否则 XORM 反射失败——这是硬性限制,不是配置问题。
- 字段名默认转为小写下划线(
CreatedAt→created_at),除非你显式指定标签:CreatedAt time.Time `xorm:"created"` - 想完全禁用自动转驼峰/下划线,用
engine.SetMapper(core.SameMapper{}),但要求结构体字段名和数据库列名严格一致(包括大小写) - MySQL 表名默认不区分大小写,但 PostgreSQL 区分;若用
SameMapper,在 PostgreSQL 上必须用双引号包裹列名:Id int64 `xorm:"\"id\" pk autoincr"` - SQL Server 中文列名必须用方括号:
Name string `xorm:"[姓名] varchar(50)"`
Sync2,而是没意识到它只管“加”,不管“改”和“删”——而线上数据库最常需要的,恰恰是后者。


















