622 字
3 分钟
迁移与初始化
GORM 迁移与初始化
AutoMigrate
学习和开发阶段可以使用:
if err := db.AutoMigrate( &User{}, &Profile{}, &Order{},); err != nil { return err}AutoMigrate 会根据模型创建表、缺失字段、索引和约束,并尽量安全地调整结构;它不是完整的版本化迁移系统,不负责任意删除字段或自动完成所有破坏性变更。
生产环境不要在每次应用启动时无条件依赖 AutoMigrate 完成复杂变更。结构变更应经过评审、备份、灰度和回滚方案。
Migrator
migrator := db.Migrator()
exists := migrator.HasTable(&User{})if !exists { if err := migrator.CreateTable(&User{}); err != nil { return err }}
if err := migrator.AddColumn(&User{}, "Nickname"); err != nil { return err}常用能力包括:
migrator.HasTable(&User{})migrator.HasColumn(&User{}, "Email")migrator.HasIndex(&User{}, "idx_users_email")migrator.RenameColumn(&User{}, "Name", "DisplayName")migrator.DropColumn(&User{}, "LegacyField")DropColumn、重命名和类型变化都可能造成数据损失或锁表,不能只看 Go 代码是否能执行。
应用启动顺序
读取配置 -> 创建 GORM 连接 -> Ping 数据库 -> 执行已审核的迁移 -> 注册 Repository/Service -> 启动 Gin HTTP 服务迁移失败时应用通常应该停止启动,而不是继续对一个结构不确定的数据库提供流量。
种子数据
种子数据应该具备幂等性:
var role Roleresult := db.Where("name = ?", "admin").First(&role)if errors.Is(result.Error, gorm.ErrRecordNotFound) { return db.Create(&Role{Name: "admin"}).Error}return result.Error不要把每次启动都会重复插入的演示数据带入生产启动流程。初始化数据、测试夹具和业务数据导入应分开管理。
版本化迁移策略
当项目需要可审计、可回滚、可按版本执行的迁移时,建议:
- 将每次结构变更写成有版本号的 SQL 或迁移文件。
- 迁移在发布流程中单独执行,并记录已执行版本。
- 应用代码兼容旧结构和新结构,采用 expand/contract 方式逐步变更。
- 先新增字段和双写,再回填数据,最后切换读路径并删除旧结构。
- 大表变更评估锁表时间、在线 DDL、复制延迟和回滚成本。
GORM 的模型定义可以作为迁移意图,但不应替代生产数据库变更评审。
外键与约束
是否由 GORM 创建外键约束,应结合团队迁移方式、数据库规范和历史表结构决定。关闭约束创建不等于取消数据完整性要求,应用和数据库至少要有一层承担约束责任。
官方资料
分享文章
生成精美分享图或复制链接,与更多人分享本文。
继续阅读
换条路线
从其他文章中稳定抽取
最后更新于 ,距今已过 77 天
部分内容可能已过时