beego 数据库迁移依赖手写sql与时间戳文件名控制顺序和状态,不使用版本表;必须用bee generate migration生成文件,文件名时间戳决定执行顺序,up/down需成对可逆且仅允许m.sql()执行原生sql,orm不可用,回滚仅支持单步撤销,文件内容禁止修改。

Beego 的数据库迁移不是靠自动建模推断,而是靠你手写 SQL + 时间戳文件名来控制执行顺序和状态。它不依赖版本表,但要求迁移文件名严格按时间戳排序,且 Up() 和 Down() 必须成对可逆。
生成迁移文件时必须用 bee generate migration
迁移文件不能手动创建,否则 bee migrate 无法识别。命令会自动生成带时间戳前缀的 Go 文件,并注册到迁移系统中:
- 执行
bee generate migration add_status_to_orders,会在database/migrations/下生成类似20240515_103022_add_status_to_orders.go的文件 - 文件名中的时间戳(如
20240515_103022)是 Beego 判断执行顺序的唯一依据,不可修改 - 结构体名(如
AddStatusToOrders_20240515_103022)由工具生成,也不建议手动改 —— 改了会导致init()中的migration.Register()失效
Up() 和 Down() 里只能写原生 SQL,不能调用 ORM
Beego 迁移层运行在 ORM 初始化之前,所以你在 Up() 或 Down() 里不能用 orm.QueryTable() 或 o.Insert() 等 ORM 方法。所有变更必须用 m.SQL("...") 显式执行:
-
Up()里写正向变更,比如m.SQL("ALTER TABLE orders ADD COLUMN status TINYINT DEFAULT 1 COMMENT '订单状态'") -
Down()里写严格对应的逆向操作,比如m.SQL("ALTER TABLE orders DROP COLUMN status")—— 注意 MySQL 8.0+ 才支持DROP COLUMN,低版本需用MODIFY重定义字段 - 不要在
Up()里插入测试数据;迁移只管结构,数据初始化应放在main()或单独的 seed 脚本中
执行迁移前确认数据库配置已加载
bee migrate 命令本身不读取 conf/app.conf,它依赖项目启动时已初始化的数据库连接。这意味着:
- 必须确保
models/init.go(或等效初始化逻辑)已被执行,且orm.RegisterDriver()和orm.RegisterDataBase()已调用成功 - 如果项目用了多环境配置(如
app.prod.conf),bee migrate默认走dev模式,需通过GO_ENV=prod bee migrate显式指定环境 - 常见报错
no database alias named default就是因为 ORM 初始化失败或别名没注册上,此时先跑bee run看是否能连上库,再执行迁移
回滚(down)只作用于最后一条已执行迁移
bee migrate down 不是“回退到某版本”,而是仅撤销最近一次成功的 Up()。它不会批量执行多个 Down(),也不会跳过中间迁移:
- 假设你有
A_20240101、B_20240201、C_20240301三条迁移,全部已执行,则bee migrate down只运行C_20240301.Down() - 若想回退到某个特定状态,得手动多次执行
down,或删掉后续迁移文件(不推荐)再重新跑up - 没有
migrate rollback --to 20240201这类功能 —— Beego 迁移设计就是线性、单步、不可跳转的
最易被忽略的一点:迁移文件一旦提交到 Git 并被团队成员执行过,就绝不能修改其中的 Up() 或 Down() 内容。哪怕只是加个空格,再次执行时 Beego 也会因校验失败而拒绝运行 —— 它靠文件内容哈希做防篡改,不是靠时间戳判断是否重跑。











