AutoMigrate 是 GORM 提供的自动表结构同步功能。定义好模型后,一行代码就能创建或更新表结构,开发阶段非常方便。
type User struct {
ID uint
Name string
Age int
Email string
}
db.AutoMigrate(&User{})
执行后会:
同时迁移多个模型:
db.AutoMigrate(&User{}, &Order{}, &Product{})
会做的:
不会做的:
这种保守策略是为了保护数据安全。
通过标签控制字段属性:
type User struct {
ID uint `gorm:"primaryKey"`
Name string `gorm:"type:varchar(100);not null"`
Email string `gorm:"uniqueIndex;size:255"`
Age int `gorm:"default:18"`
Bio string `gorm:"type:text"`
CreatedAt time.Time
}
常用标签:
| 标签 | 说明 |
|---|---|
| type | 字段类型 |
| size | 字符串长度 |
| not null | 非空约束 |
| unique | 唯一约束 |
| default | 默认值 |
| comment | 字段注释 |
| index | 创建索引 |
| uniqueIndex | 创建唯一索引 |
生产环境可能想手动控制迁移:
db.Set("gorm:table_options", "ENGINE=InnoDB").AutoMigrate(&User{})
或者完全不使用 AutoMigrate,用迁移工具如 golang-migrate、goose 等。
GORM 提供了迁移器接口,可以更精细地控制:
type Migrator interface {
AutoMigrate(dst ...interface{}) error
CreateTable(dst ...interface{}) error
DropTable(dst ...interface{}) error
HasTable(dst interface{}) bool
RenameTable(oldName, newName interface{}) error
AddColumn(dst interface{}, field string) error
DropColumn(dst interface{}, field string) error
AlterColumn(dst interface{}, field string) error
HasColumn(dst interface{}, field string) bool
RenameColumn(dst interface{}, oldName, field string) error
CreateIndex(dst interface{}, name string) error
DropIndex(dst interface{}, name string) error
HasIndex(dst interface{}, name string) bool
}
使用迁移器:
migrator := db.Migrator()
if !migrator.HasTable(&User{}) {
migrator.CreateTable(&User{})
}
if !migrator.HasColumn(&User{}, "nickname") {
migrator.AddColumn(&User{}, "nickname")
}
不同数据库的迁移行为有差异:
MySQL
ALTER TABLE 添加字段AUTO_INCREMENTPostgreSQL
SERIAL 类型UUID 类型SQLite
ALTER COLUMNSQL Server
IDENTITY 自增GORM 会处理大部分差异,但复杂迁移可能需要手写 SQL。
查看迁移执行的 SQL:
db.Debug().AutoMigrate(&User{})
或者配置日志:
newLogger := logger.New(
log.New(os.Stdout, "\r\n", log.LstdFlags),
logger.Config{
LogLevel: logger.Info,
},
)
db, _ := gorm.Open(mysql.Open(dsn), &gorm.Config{
Logger: newLogger,
})
开发阶段:每次启动时执行 AutoMigrate
func InitDB() {
db, _ := gorm.Open(mysql.Open(dsn), &gorm.Config{})
db.AutoMigrate(&User{}, &Order{}, &Product{})
}
生产环境:使用版本化迁移工具,手动执行
if os.Getenv("ENV") == "production" {
// 不自动迁移
} else {
db.AutoMigrate(&User{})
}
GORM 如何检测模型变更?
只检测结构差异,不检测约束差异(如索引类型变化)。
AutoMigrate 是开发利器,但生产环境要谨慎使用。理解它的行为边界,配合迁移工具,才能安全地管理数据库结构。