一.AutoMigrate介绍
1.介绍
在 Go 语言中,GORM支持Migration特性,支持根据Go Struct结构自动生成对应的表结构,使用
GORM
ORM 库的AutoMigrate
方法可以自动创建数据库表,确保数据库结构与定义的模型结构一致。AutoMigrate
方法非常方便,特别适合在开发阶段进行快速迭代注意:
- AutoMigrate 会创建表、缺失的外键、约束、列和索引
- 出于保护数据的目的,它 不会 删除未使用的列
- AutoMigrate 会自动创建数据库外键约束,可以在初始化时禁用此功能
db, err := gorm.Open(sqlite.Open("gorm.db"), &gorm.Config{DisableForeignKeyConstraintWhenMigrating: true, })
- 官网地址:迁移 | GORM - AutoMigrate
2.AutoMigrate
的工作原理
- 创建表:如果表不存在,
AutoMigrate
会创建它 - 更新表结构:如果表已经存在,
AutoMigrate
会检查结构体中字段的变化,例如新字段、字段类型的更改等,并进行相应的更新 - 不删除字段:
AutoMigrate
不会删除现有字段或表。如果需要删除字段,你需要手动执行此操作,或者使用 GORM 的Migrate
功能来编写复杂的迁移逻辑
二.AutoMigrate使用
1.模型定义
模型是标准的 struct,由 Go 的基本数据类型、实现了 Scanner 和 Valuer 接口的自定义类型及其指针或别名组成,如:
package modelimport ("encoding/json""fmt""strings""time""gorm.io/gorm"
)func InitSwitch(dbClient *gorm.DB) {err := dbClient.AutoMigrate(&Switch{})if err != nil {panic(fmt.Sprintf("migrate table agent fail: %v", err))}
}type Switch struct {Id uint64 `gorm:"primaryKey;autoIncrement;comment:开关ID" json:"id"` // 开关IDKey string `gorm:"column:key;type:varchar(255) not null;comment:Key;uniqueIndex:key"` // keyValue string `gorm:"column:value;type:varchar(512) not null;comment:值: 1001|1,1002|1,1003|0; eg: 1001|1 表示:1001-渠道包,1 是否开启该功能"` // 值: 1001|1,1002|1,1003|0; eg: 1001|1 表示:1001-渠道包,1 是否开启该功能Content string `gorm:"column:content;type:varchar(512) not null;comment:内容说明"` // 内容说明Name string `gorm:"column:name;type:varchar(255) not null;comment:名称"` // 名称Type uint64 `gorm:"column:type;comment:类型: 1 功能开关"` // 类型: 1 功能开关CreatedAt time.Time `json:"created_at"` // 创建时间UpdatedAt time.Time `json:"updated_at"` // 更新时间
}func (s *Switch) TableName() string {return "switch_info"
}
2.字段标签
声明 model 时,tag 是可选的,GORM支持以下 tag,标签之间用";"隔开: tag 名大小写不敏感,但建议使用
camelCase
风格
3.自动建表
通过AutoMigrate函数可以快速建表,如果表已经存在不会重复创
// 根据User结构体,自动创建表结构.
db.AutoMigrate(&Switch{})// 一次创建User、Switch、Order三个结构体对应的表结构
db.AutoMigrate(&User{}, &Switch{}, &Order{})// 可以通过Set设置附加参数,下面设置表的存储引擎为InnoDB
db.Set("gorm:table_options", "ENGINE=InnoDB").AutoMigrate(&Switch{})
使用AutoMigrate自动创建表:实际使用只需要调用InitSwitch方法即可:
package mainimport ("model"
)
func main() {// 初始化Switch,自动创建表model.InitSwitch(*gorm.DB)
}
当调用InitSwtich方法后,系统会自动地在对应的数据库下面创建响应的表,这样就可以根据实际情况修改对应的结构体,来实现表的自定义创建:
三.Schema方法
在使用AutoMigrate方法创建表时,也许会用到其他的方法,这里列举了一些常见的,如下:
1.检测表是否存在
// 检测User结构体对应的表是否存在
db.Migrator().HasTable(&User{})// 检测表名users是否存在
db.Migrator().HasTable("users")
2.建表
// 根据User结构体建表
db.Migrator().CreateTable(&User{})
3.删除表
// 删除User结构体对应的表
db.Migrator().DropTable(&User{})// 删除表名为users的表
db.Migrator().DropTable("users")
4.删除字段
// 删除User结构体对应表中的description字段
db.Migrator().DropColumn(&User{}, "Name")
5.添加索引
type User struct {gorm.ModelName string `gorm:"size:255;index:idx_name,unique"`
}// 为 Name 字段创建索引
db.Migrator().CreateIndex(&User{}, "Name")
db.Migrator().CreateIndex(&User{}, "idx_name")// 为 Name 字段删除索引
db.Migrator().DropIndex(&User{}, "Name")
db.Migrator().DropIndex(&User{}, "idx_name")// 检查索引是否存在
db.Migrator().HasIndex(&User{}, "Name")
db.Migrator().HasIndex(&User{}, "idx_name")type User struct {gorm.ModelName string `gorm:"size:255;index:idx_name,unique"`Name2 string `gorm:"size:255;index:idx_name_2,unique"`
}
// 修改索引名
db.Migrator().RenameIndex(&User{}, "Name", "Name2")
db.Migrator().RenameIndex(&User{}, "idx_name", "idx_name_2")
6.组合索引
type User struct {Name string `gorm:"index:idx_member"`Number string `gorm:"index:idx_member"`
}
四.注意事项
- 数据丢失风险:在生产环境中使用
AutoMigrate
时要小心,特别是字段类型的变更可能会导致数据丢失。建议在生产环境中使用手动迁移 - 复杂的迁移逻辑:如果需要进行更复杂的迁移逻辑(如添加索引、修改列类型等),可以使用 GORM 的
Migrator()
方法