简体   繁体   English

gorm.DB 可以自动解析外键吗?

[英]Can gorm.DB automatically resolve foreign keys?

I'm trying to use https://github.com/jinzhu/gorm to automatically map foreign keys for me but somehow either I'm doing it wrong or the library cannot do it and I'm in the wrong.我正在尝试使用https://github.com/jinzhu/gorm为我自动映射外键,但不知何故,要么我做错了,要么图书馆无法做到,而我错了。

I have the following struct s:我有以下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
}

and the following SQL tables ( edited so that currency_code is unique )以及以下 SQL 表(经过编辑以使currency_code 是唯一的

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

Now I thought that when I do something like this:现在我想,当我做这样的事情时:

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

then "USD" would get automatically mapped to a currency_id but instead it inserts new "USD" entry in currencies table for every db.Create(&rate)然后"USD"将自动映射到currency_id但它会在每个db.Create(&rate) currencies表中插入新的"USD"条目

Am I doing it wrong or it's the library?我做错了还是图书馆?

EDIT编辑

I know that I can do it by querying the DB for currency ID我知道我可以通过查询数据库的货币 ID 来做到这一点

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

but then:但随后:

  • I have to make 2 DB calls我必须进行 2 个 DB 调用
  • I don't use gorm 's foreign key mapping feature (if there is one)我不使用gorm的外键映射功能(如果有的话)

In their documentation it states:在他们的文档中,它指出:

By default when creating/updating a record, GORM will save its associations, if the association has primary key, GORM will call Update to save it, otherwise it will be created.默认情况下,在创建/更新记录时,GORM 会保存其关联,如果关联有主键,则 GORM 会调用 Update 来保存它,否则会创建它。

So when you want to map to a certain entry you must correlate it with the ID, otherwise it will create a new record.所以当你想映射到某个条目时,你必须将它与 ID 相关联,否则它会创建一个新记录。

In your case you could use the currency_code as the PRIMARY KEY for Currency (use fixed number of chars to make it faster, not varchar, like sql:"type:char(3);unique" ).你的情况,你可以使用currency_code作为PRIMARY KEY Currency (字符的使用年限,使其更快,而不是为varchar,就像sql:"type:char(3);unique" )。

This would eliminate the need of a search by ID anymore, it would just find "USD" as primary key and use it => no more multiple records per currency.这将不再需要通过 ID 进行搜索,它只会找到“USD”作为主键并使用它 => 每种货币不再有多个记录。 Also if there is a currency that it does not have, it will create it in the Currency table.此外,如果有一种它没有的货币,它会在Currency表中创建它。

Also you can eliminate the gorm:"ForeignKey:CurrencyID" struct tag and let GORM create it's own tables with AutoMigrate , and would create the tables with the appropriate FK:您也可以消除gorm:"ForeignKey:CurrencyID"结构标记,让 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{})

In recently released GORM 2.0, foreign keys get added to your database automatically provided your GORM tags are correct.在最近发布的 GORM 2.0 中,只要您的 GORM 标签正确,外键就会自动添加到您的数据库中。 You can say AutoMigrate got smarter.您可以说 AutoMigrate 变得更智能了。

Just upgrade and use the new imports只需升级并使用新的进口

go get gorm.io/gorm

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

PS: There are some breaking changes with the new version, kindly check the official relase note for more info https://gorm.io/docs/v2_release_note.html PS:新版本有一些重大变化,请查看官方发布说明了解更多信息https://gorm.io/docs/v2_release_note.html

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM