# 遷移
## AutoMigrate
AutoMigrate 用于自動遷移您的 schema,保持您的 schema 是最新的。
**注意:**AutoMigrate***\* 只會創建表,它會忽略外鍵、約束、列和索引。為了保護您的數據,它**不會**更改現有列的類型或刪除未使用的列。
```go
db.AutoMigrate(&User{})
db.AutoMigrate(&User{}, &Product{}, &Order{})
// 創建表時添加后綴
db.Set("gorm:table_options", "ENGINE=InnoDB").AutoMigrate(&User{})
```
**注意** AutoMigrate 會自動創建數據庫外鍵約束,您可以在初始化時禁用此功能,例如:
```go
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
```go
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
HasColumn(dst interface{}, field string) bool
RenameColumn(dst interface{}, oldName, field string) error
ColumnTypes(dst interface{}) ([]*sql.ColumnType, 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
}
```
### 當前數據庫
返回當前使用的數據庫名
```go
db.Migrator().CurrentDatabase()
```
### 表
```go
// 為 `User` 創建表
db.Migrator().CreateTable(&User{})
// 將 "ENGINE=InnoDB" 添加到創建 `User` 的 SQL 里去
db.Set("gorm:table_options", "ENGINE=InnoDB").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")
```
### 列
```go
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)
```
### 約束
```go
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")
```
### 索引
```go
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 會在自動遷移和創建表時創建約束,查看 [約束](http://v2.gorm.io/zh_CN/docs/constraints.html) 或 [數據庫索引](http://v2.gorm.io/zh_CN/docs/indexes.html) 獲取詳情
## 其他遷移工具
GORM 的 AutoMigrate 在大多數情況下都工作得很好,但如果您正在尋找更嚴格的遷移工具,GORM 提供一個通用數據庫接口,可能對您有幫助。
```go
// returns `*sql.DB`
db.DB()
```
查看 [通用接口](http://v2.gorm.io/zh_CN/docs/generic_interface.html) 獲取詳情。