GORM——AutoMigrate

Stella981
• 阅读 1203

AutoMigrate 用于自动迁移您的 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 COLUMNDROP COLUMN,当你试图修改表结构,GORM 将创建一个新表、复制所有数据、删除旧表、重命名新表。

一些版本的 MySQL 不支持 rename 列,索引。GORM 将基于您使用 MySQL 的版本执行不同 SQL

type Migrator interface {
    // AutoMigrate
    AutoMigrate(dst ...interface{}) error

    // Database
    CurrentDatabase() string
    FullDataTypeOf(*schema.Field) clause.Expr

    // Tables
    CreateTable(dst ...interface{}) error
    DropTable(dst ...interface{}) error
    HasTable(dst interface{}) bool
    RenameTable(oldName, newName interface{}) error

    // Columns
    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)

    // Views
    CreateView(name string, option ViewOption) error
    DropView(name string) error

    // Constraints
    CreateConstraint(dst interface{}, name string) error
    DropConstraint(dst interface{}, name string) error
    HasConstraint(dst interface{}, name string) bool

    // Indexes
    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
}

当前数据库

返回当前使用的数据库名

db.Migrator().CurrentDatabase()

// Create table for `User`

db.Migrator().CreateTable(&User{})

// Append "ENGINE=InnoDB" to the creating table SQL for `User`

db.Set("gorm:table_options", "ENGINE=InnoDB").Migrator().CreateTable(&User{})

// Check table for `User` exists or not

db.Migrator().HasTable(&User{})

db.Migrator().HasTable("users")

// Drop table if exists (will ignore or delete foreign key constraints when dropping)

db.Migrator().DropTable(&User{})

db.Migrator().DropTable("users")

// Rename old table to new table

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")

// 检查字段是否存在

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{}) ([]*sql.ColumnType, error)

约束

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

  Name 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.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 会在自动迁移和创建表时创建约束,查看 约束数据库索引 获取详情

其他迁移工具

GORM 的 AutoMigrate 在大多数情况下都工作得很好,但如果您正在寻找更严格的迁移工具,GORM 提供一个通用数据库接口,可能对您有帮助。

// returns `*sql.DB`

db.DB()

查看 通用接口 获取详情。

本文同步分享在 博客“羊羽”(other)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

点赞
收藏
评论区
推荐文章
blmius blmius
2年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Karen110 Karen110
2年前
一篇文章带你了解JavaScript日期
日期对象允许您使用日期(年、月、日、小时、分钟、秒和毫秒)。一、JavaScript的日期格式一个JavaScript日期可以写为一个字符串:ThuFeb02201909:59:51GMT0800(中国标准时间)或者是一个数字:1486000791164写数字的日期,指定的毫秒数自1970年1月1日00:00:00到现在。1\.显示日期使用
Jacquelyn38 Jacquelyn38
2年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Souleigh ✨ Souleigh ✨
2年前
前端性能优化 - 雅虎军规
无论是在工作中,还是在面试中,web前端性能的优化都是很重要的,那么我们进行优化需要从哪些方面入手呢?可以遵循雅虎的前端优化35条军规,这样对于优化有一个比较清晰的方向.35条军规1.尽量减少HTTP请求个数——须权衡2.使用CDN(内容分发网络)3.为文件头指定Expires或CacheControl,使内容具有缓存性。4.避免空的
Wesley13 Wesley13
2年前
SQL 删除外键列
一 SQL删除列的语句是:altertabletableNamedropcolumncolumnName(其中,tableName为表名,columnName为列名)但是,如果某列有约束时,不能直接删除,需要先删除约束,再删除列。如果某个列是外键,在不知道外键约束名称的情况下,那么首先是查找外键约束名称,根据名称删除约束,
Easter79 Easter79
2年前
sqlserver2005创建唯一约束的方法
对于一个表中非主键列的指定列,唯一(UNIQUE约束|:强制非主键上的实体完整性的约束。UNIQUE约束确保未输入重复值,并创建一个索引以增强性能。)约束确保不会输入重复的值。例如,在employee表中emp\_id列是主键,可以定义一个唯一约束来要求表中社会安全号码(ssn)列的项是唯一的。在数据库关系图中,可以使用"索引/键"属性页创建、
Wesley13 Wesley13
2年前
mysql 外键(foreign key)的详解和实例
外键具有保持数据完整性和一致性的机制,对业务处理有着很好的校验作用。白话简介user表:id为主键profile表:uid为主键简单来说,若表profile的uid列作为表外键(外建名称:user_profile),以表user 做为主表,以其id列做为参照(referenc
Wesley13 Wesley13
2年前
35岁是技术人的天花板吗?
35岁是技术人的天花板吗?我非常不认同“35岁现象”,人类没有那么脆弱,人类的智力不会说是35岁之后就停止发展,更不是说35岁之后就没有机会了。马云35岁还在教书,任正非35岁还在工厂上班。为什么技术人员到35岁就应该退役了呢?所以35岁根本就不是一个问题,我今年已经37岁了,我发现我才刚刚找到自己的节奏,刚刚上路。
Wesley13 Wesley13
2年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_