教程

迁移

qianmoQqianmoQ· 更新于 2026-09-23· 阅读 16 分钟· 0 次阅读

登录后可跨设备保存划线和私人笔记登录

自动迁移

自动迁移您的 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()

详情请参阅通用接口。

GitHub tag (latest SemVer)

评论

登录后参与评论

正在加载评论…