AutoMigrate
AutoMigrate 用于自动迁移您的 schema,保持您的 schema 是最新的。
注意: AutoMigrate 会创建表、缺失的外键、约束、列和索引。 It will change existing column’s type if its size, precision changed, or if it’s changing from non-nullable to nullable. 出于保护您数据的目的,它 不会 删除未使用的列
db.AutoMigrate(&User{})db.AutoMigrate(&User{}, &Product{}, &Order{})// 创建表时添加后缀db.Set("gorm:table_options", "ENGINE=InnoDB").AutoMigrate(&User{})
注意 AutoMigrate 会自动创建数据库外键约束,您可以在初始化时禁用此功能,例如:
db, err := gorm.Open(sqlite.Open("gorm.db"), &gorm.Config{DisableForeignKeyConstraintWhenMigrating: true,})
Migrator 接口
GORM 提供了 Migrator 接口,该接口为每个数据库提供了统一的 API 接口,可用来为您的数据库构建独立迁移,例如:
SQLite 不支持 ALTER COLUMN、DROP COLUMN,当你试图修改表结构,GORM 将创建一个新表、复制所有数据、删除旧表、重命名新表。
一些版本的 MySQL 不支持 rename 列,索引。GORM 将基于您使用 MySQL 的版本执行不同 SQL
type Migrator interface {// AutoMigrateAutoMigrate(dst ...interface{}) error// DatabaseCurrentDatabase() stringFullDataTypeOf(*schema.Field) clause.Expr// TablesCreateTable(dst ...interface{}) errorDropTable(dst ...interface{}) errorHasTable(dst interface{}) boolRenameTable(oldName, newName interface{}) errorGetTables() (tableList []string, err error)// ColumnsAddColumn(dst interface{}, field string) errorDropColumn(dst interface{}, field string) errorAlterColumn(dst interface{}, field string) errorMigrateColumn(dst interface{}, field *schema.Field, columnType ColumnType) errorHasColumn(dst interface{}, field string) boolRenameColumn(dst interface{}, oldName, field string) errorColumnTypes(dst interface{}) ([]ColumnType, error)// ViewsCreateView(name string, option ViewOption) errorDropView(name string) error// ConstraintsCreateConstraint(dst interface{}, name string) errorDropConstraint(dst interface{}, name string) errorHasConstraint(dst interface{}, name string) bool// IndexesCreateIndex(dst interface{}, name string) errorDropIndex(dst interface{}, name string) errorHasIndex(dst interface{}, name string) boolRenameIndex(dst interface{}, oldName, newName string) error}
当前数据库
返回当前使用的数据库名
db.Migrator().CurrentDatabase()
表
// 为 `User` 创建表db.Migrator().CreateTable(&User{})// 将 "ENGINE=InnoDB" 添加到创建 `User` 的 SQL 里去db.Set("gorm:table_options", "ENGINE=InnoDB").Migrator().CreateTable(&User{})// 检查 `User` 对应的表是否存在db.Migrator().HasTable(&User{})db.Migrator().HasTable("users")// 如果存在表则删除(删除时会忽略、删除外键约束)db.Migrator().DropTable(&User{})db.Migrator().DropTable("users")// 重命名表db.Migrator().RenameTable(&User{}, &UserInfo{})db.Migrator().RenameTable("users", "user_infos")
列
type User struct {Name string}// 添加 name 字段db.Migrator().AddColumn(&User{}, "Name")// 删除 name 字段db.Migrator().DropColumn(&User{}, "Name")// 修改 name 字段db.Migrator().AlterColumn(&User{}, "Name")// 检查 name 字段是否存在db.Migrator().HasColumn(&User{}, "Name")type User struct {Name stringNewName string}// 字段重命名db.Migrator().RenameColumn(&User{}, "Name", "NewName")db.Migrator().RenameColumn(&User{}, "name", "new_name")// 字段类型db.Migrator().ColumnTypes(&User{}) ([]gorm.ColumnType, error)type ColumnType interface {Name() stringDatabaseTypeName() string // varcharColumnType() (columnType string, ok bool) // varchar(64)PrimaryKey() (isPrimaryKey bool, ok bool)AutoIncrement() (isAutoIncrement bool, ok bool)Length() (length int64, ok bool)DecimalSize() (precision int64, scale int64, ok bool)Nullable() (nullable bool, ok bool)Unique() (unique bool, ok bool)ScanType() reflect.TypeComment() (value string, ok bool)DefaultValue() (value string, ok bool)}
Views
Create views by ViewOption. About ViewOption:
Queryis a subquery, which is required.- If
Replaceis true, execCREATE OR REPLACEotherwise execCREATE. - If
CheckOptionis not empty, append to sql, e.g.WITH LOCAL CHECK OPTION.
NOTE SQLite currently does not support
ReplaceinViewOption
query := db.Model(&User{}).Where("age > ?", 20)// Create Viewdb.Migrator().CreateView("users_pets", gorm.ViewOption{Query: query})// CREATE VIEW `users_view` AS SELECT * FROM `users` WHERE age > 20// Create or Replace Viewdb.Migrator().CreateView("users_pets", gorm.ViewOption{Query: query, Replace: true})// CREATE OR REPLACE VIEW `users_pets` AS SELECT * FROM `users` WHERE age > 20// Create View With Check Optiondb.Migrator().CreateView("users_pets", gorm.ViewOption{Query: query, CheckOption: "WITH CHECK OPTION"})// CREATE VIEW `users_pets` AS SELECT * FROM `users` WHERE age > 20 WITH CHECK OPTION// Drop Viewdb.Migrator().DropView("users_pets")// DROP VIEW IF EXISTS "users_pets"
Constraints
type UserIndex struct {Name string `gorm:"check:name_checker,name <> 'jinzhu'"`}// Create constraintdb.Migrator().CreateConstraint(&User{}, "name_checker")// Drop constraintdb.Migrator().DropConstraint(&User{}, "name_checker")// Check constraint existsdb.Migrator().HasConstraint(&User{}, "name_checker")
Create foreign keys for relations
type User struct {gorm.ModelCreditCards []CreditCard}type CreditCard struct {gorm.ModelNumber stringUserID uint}// create database foreign key for user & credit_cardsdb.Migrator().CreateConstraint(&User{}, "CreditCards")db.Migrator().CreateConstraint(&User{}, "fk_users_credit_cards")// ALTER TABLE `credit_cards` ADD CONSTRAINT `fk_users_credit_cards` FOREIGN KEY (`user_id`) REFERENCES `users`(`id`)// check database foreign key for user & credit_cards exists or notdb.Migrator().HasConstraint(&User{}, "CreditCards")db.Migrator().HasConstraint(&User{}, "fk_users_credit_cards")// drop database foreign key for user & credit_cardsdb.Migrator().DropConstraint(&User{}, "CreditCards")db.Migrator().DropConstraint(&User{}, "fk_users_credit_cards")
Indexes
type User struct {gorm.ModelName string `gorm:"size:255;index:idx_name,unique"`}// Create index for Name fielddb.Migrator().CreateIndex(&User{}, "Name")db.Migrator().CreateIndex(&User{}, "idx_name")// Drop index for Name fielddb.Migrator().DropIndex(&User{}, "Name")db.Migrator().DropIndex(&User{}, "idx_name")// Check Index existsdb.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"`}// Rename index namedb.Migrator().RenameIndex(&User{}, "Name", "Name2")db.Migrator().RenameIndex(&User{}, "idx_name", "idx_name_2")
约束
GORM creates constraints when auto migrating or creating table, see Constraints or Database Indexes for details
Atlas Integration
Atlas is an open-source database migration tool that has an official integration with GORM.
While GORM’s AutoMigrate feature works in most cases, at some point you may need to switch to a versioned migrations strategy.
Once this happens, the responsibility for planning migration scripts and making sure they are in line with what GORM expects at runtime is moved to developers.
Atlas can automatically plan database schema migrations for developers using the official GORM Provider. After configuring the provider you can automatically plan migrations by running:
atlas migrate diff --env gorm
To learn how to use Atlas with GORM, check out the official documentation.
Other Migration Tools
To use GORM with other Go-based migration tools, GORM provides a generic DB interface that might be helpful for you.
// returns `*sql.DB`db.DB()
Refer to Generic Interface for more details.