迁移
自动迁移
自动迁移您的 schema,使 schema 保持最新。
注意: AutoMigrate 会创建表、缺失的外键、约束、列和索引。当列的大小、精度发生变化,或从非空变为可空时,它会修改现有列的类型。它不会删除未使用的列,以保护您的数据。
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 某些版本不支持重命名列和索引,GORM 会根据您使用的 MySQL 版本执行不同的 SQL
type Migrator interface {
AutoMigrate(dst ...interface{}) error
CurrentDatabase() string
FullDataTypeOf(*schema.Field) clause.Expr
CreateTable(dst ...interface{}) error
DropTable(dst ...interface{}) error
HasTable(dst interface{}) bool
RenameTable(oldName, newName interface{}) error
GetTables() (tableList []string, err error)
AddColumn(dst interface{}, field string) error
DropColumn(dst interface{}, field string) error
AlterColumn(dst interface{}, field string) error
MigrateColumn(dst interface{}, field *schema.Field, columnType ColumnType) error
HasColumn(dst interface{}, field string) bool
RenameColumn(dst interface{}, oldName, field string) error
ColumnTypes(dst interface{}) ([]ColumnType, error)
CreateView(name string, option ViewOption) error
DropView(name string) error
CreateConstraint(dst interface{}, name string) error
DropConstraint(dst interface{}, name string) error
HasConstraint(dst interface{}, name string) bool
CreateIndex(dst interface{}, name string) error
DropIndex(dst interface{}, name string) error
HasIndex(dst interface{}, name string) bool
RenameIndex(dst interface{}, oldName, newName string) error
}CurrentDatabase
返回当前使用的数据库名称
db.Migrator().CurrentDatabase()表
db.Migrator().CreateTable(&User{})
db.Set("gorm:table_options", "ENGINE=InnoDB").Migrator().CreateTable(&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
}
db.Migrator().AddColumn(&User{}, "Name")
db.Migrator().DropColumn(&User{}, "Name")
db.Migrator().AlterColumn(&User{}, "Name")
db.Migrator().HasColumn(&User{}, "Name")
type User struct {
Name string
NewName 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() string
DatabaseTypeName() string
ColumnType() (columnType string, ok bool)
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.Type
Comment() (value string, ok bool)
DefaultValue() (value string, ok bool)
}视图
通过 ViewOption 创建视图。关于 ViewOption:
Query是一个子查询,为必填项。- 如果
Replace为 true,则执行CREATE OR REPLACE,否则执行CREATE。 - 如果
CheckOption非空,则追加到 SQL,例如WITH LOCAL CHECK OPTION。
注意 SQLite 目前不支持
ViewOption中的Replace
query := db.Model(&User{}).Where("age > ?", 20)
db.Migrator().CreateView("users_pets", gorm.ViewOption{Query: query})
db.Migrator().CreateView("users_pets", gorm.ViewOption{Query: query, Replace: true})
db.Migrator().CreateView("users_pets", gorm.ViewOption{Query: query, CheckOption: "WITH CHECK OPTION"})
db.Migrator().DropView("users_pets")
约束
type UserIndex struct {
Name string `gorm:"check:name_checker,name <> 'jinzhu'"`
}
db.Migrator().CreateConstraint(&User{}, "name_checker")
db.Migrator().DropConstraint(&User{}, "name_checker")
db.Migrator().HasConstraint(&User{}, "name_checker")为关系创建外键
type User struct {
gorm.Model
CreditCards []CreditCard
}
type CreditCard struct {
gorm.Model
Number string
UserID uint
}
db.Migrator().CreateConstraint(&User{}, "CreditCards")
db.Migrator().CreateConstraint(&User{}, "fk_users_credit_cards")
db.Migrator().HasConstraint(&User{}, "CreditCards")
db.Migrator().HasConstraint(&User{}, "fk_users_credit_cards")
db.Migrator().DropConstraint(&User{}, "CreditCards")
db.Migrator().DropConstraint(&User{}, "fk_users_credit_cards")索引
type User struct {
gorm.Model
Name string `gorm:"size:255;index:idx_name,unique"`
}
db.Migrator().CreateIndex(&User{}, "Name")
db.Migrator().CreateIndex(&User{}, "idx_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.Model
Name 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")约束
GORM 在自动迁移或创建表时会创建约束,详情请参阅约束或数据库索引
Atlas 集成
Atlas 是一个开源数据库迁移工具,与 GORM 有官方集成。
虽然 GORM 的 AutoMigrate 功能在大多数情况下有效,但在某些时候您可能需要切换到版本化迁移策略。
一旦发生这种情况,规划迁移脚本并确保它们与 GORM 运行时的期望一致的责任就转移到了开发者身上。
Atlas 可以使用官方的 GORM Provider 为开发者自动规划数据库 schema 迁移。配置 provider 后,您可以通过运行以下命令自动规划迁移:
atlas migrate diff --env gorm要了解如何在 GORM 中使用 Atlas,请查看官方文档。
其他迁移工具
要在 GORM 中使用其他基于 Go 的迁移工具,GORM 提供了一个通用的 DB 接口,可能对您有所帮助。
db.DB()详情请参阅通用接口。
评论
登录后参与评论
KnowForge