`gorm`忽略`sql:”index”`标签。

huangapple go评论128阅读模式
英文:

`gorm` Ignoring `sql:"index"` Tags

问题

为什么gorm忽略了sql:"index"标签?没有创建索引。

这里使用的数据库是PostgreSQL(导入_ "github.com/lib/pq")。使用了以下Model结构体(因为默认的gorm.Model使用自增数字 - serial - 作为主键,而我想自己设置id):

  1. type Model struct {
  2. ID int64 `sql:"type:bigint PRIMARY KEY;default:0"`
  3. CreatedAt time.Time
  4. UpdatedAt time.Time
  5. DeletedAt *time.Time `sql:"index"`
  6. }

其中一个实际的模型是:

  1. type TUHistory struct {
  2. Model
  3. TUID int64 `json:"tu_id,string" gorm:"column:tu_id" sql:"index"`
  4. }
  5. func (x *TUHistory) TableName() string {
  6. return "tu_history"
  7. }

通过db.CreateTable(&TUHistory{})创建表,除了索引之外,表被正确创建。

作为临时解决方法,我使用db.Model(&TUHistory{}).AddIndex("ix_tuh_tu_id", "tu_id")来创建索引。

英文:

Why gorm is ignoring sql:"index" tags? No indexes got created.

Database in use here is PostgreSQL (importing _ "github.com/lib/pq"). This Model struct is used (because default gorm.Model uses an auto increment number - serial - as primary key and I wanted to set id myself):

  1. type Model struct {
  2. ID int64 `sql:"type:bigint PRIMARY KEY;default:0"`
  3. CreatedAt time.Time
  4. UpdatedAt time.Time
  5. DeletedAt *time.Time `sql:"index"`
  6. }

And one of actual models is:

  1. type TUHistory struct {
  2. Model
  3. TUID int64 `json:"tu_id,string" gorm:"column:tu_id" sql:"index"`
  4. }
  5. func (x *TUHistory) TableName() string {
  6. return "tu_history"
  7. }

And the table is created by db.CreateTable(&TUHistory{}) which creates the table correctly except for indexes.

As a temporary work around, I do db.Model(&TUHistory{}).AddIndex("ix_tuh_tu_id", "tu_id") to create indexes.

答案1

得分: 2

根据我的经验,db.CreateTable 只会创建表和字段。你最好使用 AutoMigrate 函数来迁移你想要的模型结构:

  1. db, err := gorm.Open("postgres", connectionString)
  2. ...
  3. // 错误检查
  4. ...
  5. db.AutoMigrate(&Model)

另外,我尝试使用你发布的模型进行自动迁移,但是出现了一个错误,提示不允许有多个主键,所以我将模型更改为:

  1. type Model struct {
  2. Id int64 `sql:"type:bigint;default:0"`
  3. CreatedAt time.Time
  4. UpdatedAt time.Time
  5. DeletedAt *time.Time `sql:"index"`
  6. }

然后,AutoMigrate 成功地创建了所有的主键和索引。

编辑:

查看 GORM 的 README,在这个示例中,Email 结构如下:

  1. type Email struct {
  2. ID int
  3. UserID int `sql:"index"` // 外键(属于),tag `index` 会在使用 AutoMigrate 时为该字段创建索引
  4. Email string `sql:"type:varchar(100);unique_index"` // 设置字段的 SQL 类型,tag `unique_index` 会创建唯一索引
  5. Subscribed bool
  6. }

注意 UserId 字段的注释,它表示在使用 AutoMigrate 时会创建索引。

另外,值得一提的是,我们可以看一下 AutoMigrate 是如何工作的:

  1. // 自动迁移
  2. db.AutoMigrate(&User{})
  3. db.Set("gorm:table_options", "ENGINE=InnoDB").AutoMigrate(&User{})
  4. db.AutoMigrate(&User{}, &Product{}, &Order{})
  5. // 随意更改你的结构,AutoMigrate 会保持你的数据库是最新的。
  6. // AutoMigrate 只会添加*新的列*和*新的索引*,
  7. // 不会更新当前列的类型或删除未使用的列,以保护你的数据。
  8. // 如果表不存在,AutoMigrate 会自动创建表。
  9. [1]: https://github.com/jinzhu/gorm#define-models-structs
  10. [2]: https://github.com/jinzhu/gorm#migration
英文:

From my experience, the db.CreateTable only creates the table and it's fields. You are better off using the AutoMigrate function with the model structure that you want to migrate:

  1. db, err := gorm.Open("postgres", connectionString)
  2. ...
  3. // error checking
  4. ...
  5. db.AutoMigrate(&Model)

Also, I tried AutoMigrating the model you posted and got an error saying that multiple primary keys are not allowed, so I changed the model to:

  1. type Model struct {
  2. Id int64 `sql:"type:bigint;default:0"`
  3. CreatedAt time.Time
  4. UpdatedAt time.Time
  5. DeletedAt *time.Time `sql:"index"`
  6. }

and the AutoMigration created all PKs and indexes just fine.

Edit:

Checking the GORM's README, on this example, the Email structure goes as:

  1. type Email struct {
  2. ID int
  3. UserID int `sql:"index"` // Foreign key (belongs to), tag `index` will create index for this field when using AutoMigrate
  4. Email string `sql:"type:varchar(100);unique_index"` // Set field's sql type, tag `unique_index` will create unique index
  5. Subscribed bool
  6. }

Notice the comment on the UserId field saying it will create the index when using AutoMigrate.

Also, it's worth taking a look at how the AutoMigrate does it's job:

  1. // Automating Migration
  2. db.AutoMigrate(&User{})
  3. db.Set("gorm:table_options", "ENGINE=InnoDB").AutoMigrate(&User{})
  4. db.AutoMigrate(&User{}, &Product{}, &Order{})
  5. // Feel free to change your struct, AutoMigrate will keep your database up-to-date.
  6. // AutoMigrate will ONLY add *new columns* and *new indexes*,
  7. // WON'T update current column's type or delete unused columns, to protect your data.
  8. // If the table is not existing, AutoMigrate will create the table automatically.

huangapple
  • 本文由 发表于 2015年12月4日 20:07:12
  • 转载请务必保留本文链接:https://go.coder-hub.com/34088054.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定