beego 数据库迁移依赖手写带时间戳的 sql 脚本,通过 bee migrate 按序执行 up/down,不支持自动建表、跨版本跳转或语法校验;迁移文件须用 bee generate migration 生成,init 中 register 不可删,sql 需可逆且适配目标数据库,回滚仅限最后一次,协作易因时间戳冲突出错。

Beego 的数据库迁移不是自动建表,而是靠手写 SQL 脚本控制结构变更,bee migrate 执行时按时间戳顺序运行,不支持跨版本跳转或自动推断差异。
生成迁移文件必须用 bee generate migration
迁移文件名带时间戳,Beego 靠它排序和去重。不能手动创建空文件或改名,否则 bee migrate 会跳过或报错。
- 执行
bee generate migration add_status_to_orders后,会在database/migrations/下生成类似20240515_103022_add_status_to_orders.go的文件 - 文件里
Up()和Down()方法必须都实现,哪怕Down()是空操作(如删除字段后无法还原,也得写个m.SQL("SELECT 1")占位) - 别删掉
init()函数里的migration.Register(...),这是 Beego 发现迁移脚本的唯一方式
Up() 和 Down() 中的 SQL 必须可逆且兼容目标数据库
Beego 不做语法校验,也不连接数据库预检。SQL 写错,bee migrate 就直接报错中断,已执行的部分不会回滚。
- MySQL 下加字段推荐用
ADD COLUMN age INT DEFAULT 0 COMMENT '年龄',避免用AFTER子句——某些版本不支持,且迁移回滚时难处理 - 删除字段或索引前,先确认没有业务代码依赖它;
Down()里不要写DROP TABLE,除非你真打算丢数据 - 如果要改字段类型(如
VARCHAR(50)→VARCHAR(100)),MySQL 允许,但 PostgreSQL 需用USING显式转换,得按实际 DB 类型写两套逻辑
bee migrate 执行时默认只跑未执行过的 Up()
它不读取数据库当前结构,只查内部记录的“已执行迁移列表”。这个列表存在 Beego 自己维护的 beego_migrations 表里(首次运行自动建),不是靠比对 schema。
- 执行
bee migrate就是跑所有未执行的Up();加-v参数能看到每条 SQL 实际执行过程 - 回滚用
bee migrate -r,只回退最后一次成功的Up(),对应调用一次Down();不能指定回退到某版本 - 如果某次
Up()失败了,后续迁移全卡住,必须手动修复 SQL 或在 DB 里删掉beego_migrations表中那条失败记录(慎用)
真正麻烦的不是写 SQL,而是团队协作时多人同时提交迁移文件导致时间戳冲突,或者本地测试用 Down() 清数据后忘了重新 Up() 就提测。这些地方没日志、没 dry-run 模式,只能靠人工核对和测试环境隔离。











