gorm.db能自动解析外键吗?

svdrlsy4  于 2021-06-21  发布在  Mysql
关注(0)|答案(2)|浏览(572)

我试着用https://github.com/jinzhu/gorm 自动为我Map外键,但不知何故,要么我做错了,要么图书馆做不到,我做错了。
我有以下几点 struct 学生:

type Currency struct {
  ID           uint64 `gorm:"primary_key"`
  CurrencyCode string `gorm:"size:3"`
}

type Rate struct {
  ID          uint64 `gorm:"primary_key"`
  CurrencyID  uint64
  Currency    Currency `gorm:"ForeignKey:CurrencyID"`
  Price       float64
}

以及以下sql表(编辑以使货币代码唯一)

CREATE TABLE `rates` (
  `id` serial PRIMARY KEY,
  `currency_id` bigint unsigned NOT NULL,
  `price` decimal(12,2) NOT NULL,
  CONSTRAINT `fk_rate_currency`
    FOREIGN KEY (currency_id) REFERENCES currencies(id)
);

CREATE TABLE `currencies` (
  `id` serial PRIMARY KEY,
  `currency_code` char(3) NOT NULL UNIQUE
);

现在我想当我这样做的时候:

rate := Rate{
  Currency: Currency{
    CurrencyCode: "USD",
  },
  Price: 123,
}
db, _  := gorm.Open("mysql", ...)
db.Create(&rate)

那么 "USD" 会自动Map到 currency_id 但它却插入了新的 "USD" 进入 currencies 每张table db.Create(&rate) 是我做错了还是图书馆?
编辑
我知道我可以通过查询db中的货币id来实现

curr := db.Currency{}
db.Where("currency_code = ?", "USD").First(&curr)
// use curr with proper ID

但是后来:
我得打2个分贝的电话
我不使用 gorm 的外键Map功能(如果有)

xhv8bpkk

xhv8bpkk1#

在最近发布的gorm2.0中,只要gorm标记正确,外键就会自动添加到数据库中。你可以说自动迁移变得更聪明了。
只需升级和使用新的导入

go get gorm.io/gorm

import (
  "gorm.io/gorm"
  "gorm.io/driver/sqlite" //or whatever driver
)

ps:新版本有一些突破性的变化,请查看官方的更新说明了解更多信息https://gorm.io/docs/v2_release_note.html

s4n0splo

s4n0splo2#

在他们的文件中指出:
默认情况下,在创建/更新记录时,gorm将保存其关联,如果关联具有主键,gorm将调用update保存它,否则将创建它。
因此,当您要Map到某个条目时,必须将其与id相关联,否则它将创建一个新记录。
你可以用 currency_code 作为的主键 Currency (使用固定数量的字符使其更快,而不是varchar,如 sql:"type:char(3);unique" ).
这样就不再需要按id进行搜索,只需找到“usd”作为主键并使用它=>每个货币不再有多个记录。另外,如果有一种货币它没有,它会在 Currency table。
也可以消除 gorm:"ForeignKey:CurrencyID" struct标记,让gorm使用automigrate创建自己的表,并使用适当的fk创建表:

db := gorm.Open("mysql", ...)
db.Set("gorm:table_options", "ENGINE=InnoDB")
db.Set("gorm:table_options", "collation_connection=utf8_general_ci")
// Migrate the schema
db.AutoMigrate(&models.Currency{})
db.AutoMigrate(&models.Rate{})

相关问题