英文:
Using a pointer reference to a foreign-key related model in Gorm (golang)
问题
假设你有以下数据库模型:
package storage
type Country struct {
ID string `json:"id" gorm:"type:uuid"`
Name string `json:"name"`
Code string `json:"code"`
}
type City struct {
ID string `json:"id" gorm:"type:uuid"`
Name string `json:"name"`
Code *string `json:"code"`
CountryId string `json:"country_id"`
Country *Country `json:"country" gorm:"references:ID"`
IATA *string `json:"iata"`
Latitude *string `json:"latitude"`
Longitude *string `json:"longitude"`
}
为了更容易理解是否已经连接了 Country(在 SQL 中)或者没有连接(例如 if city.Country == nil {panic("for whatever reason")}
),城市应该有一个指向 Country 模型的指针。
当我尝试获取所有城市的列表时出现了问题:
package example
var cities []storage.City
tx.Joins("Country").Find(&cities)
在这里,所有的城市都已经从数据库中获取到了,但是所有的城市的国家都变成了相同的。
期望的输出:
[
{
ID:51e415ab-4301-4268-9345-deed6b1d72f6
Name:Bergen
Code:0xc0004d6ec0
CountryId:0bd3890c-b6b7-4b27-8071-55c8f64562bb
Country:{
ID:0bd3890c-b6b7-4b27-8071-55c8f64562bb
Name:Norwegen
Code:NO
}
SkyScannerId:0xc0004d6ee0
IATA:0xc0004d6ef0
Latitude:0xc0004d6f00
Longitude:0xc0004d6f10
},
{
ID:2468c7f0-0275-4bff-8b7e-4e87bfa63604
Name:Banská Bystrica
Code:0xc0004d6bc0
CountryId:00ba76d3-9591-4d45-a39d-f554375d790f
Country: {
ID:00ba76d3-9591-4d45-a39d-f554375d790f
Name:Slovakei
Code:SK
}
SkyScannerId:<nil>
IATA:<nil>
Latitude:0xc0004d6c00
Longitude:0xc0004d6c10
},
{
ID:75501988-3c80-4ef9-8081-73d20cbcc29b
Name:Prag
Code:0xc0004d6a60
CountryId:f4e819b2-5c1a-43f9-bfa1-fe56b6ee173e
Country:{
ID:f4e819b2-5c1a-43f9-bfa1-fe56b6ee173e
Name:Tschechien
Code:CZ
}
SkyScannerId:0xc0004d6a90
IATA:0xc0004d6aa0
Latitude:0xc0004d6ac0
Longitude:0xc0004d6ad0
}
]
实际的输出:
[
{
ID:51e415ab-4301-4268-9345-deed6b1d72f6
Name:Bergen
Code:0xc0004d6ec0
CountryId:0bd3890c-b6b7-4b27-8071-55c8f64562bb
Country:{
ID:f4e819b2-5c1a-43f9-bfa1-fe56b6ee173e
Name:Tschechien
Code:CZ
}
SkyScannerId:0xc0004d6ee0
IATA:0xc0004d6ef0
Latitude:0xc0004d6f00
Longitude:0xc0004d6f10
},
{
ID:2468c7f0-0275-4bff-8b7e-4e87bfa63604
Name:Banská Bystrica
Code:0xc0004d6bc0
CountryId:00ba76d3-9591-4d45-a39d-f554375d790f
Country:{
ID:f4e819b2-5c1a-43f9-bfa1-fe56b6ee173e
Name:Tschechien
Code:CZ
}
SkyScannerId:<nil>
IATA:<nil>
Latitude:0xc0004d6c00
Longitude:0xc0004d6c10
},
{
ID:75501988-3c80-4ef9-8081-73d20cbcc29b
Name:Prag
Code:0xc0004d6a60
CountryId:f4e819b2-5c1a-43f9-bfa1-fe56b6ee173e
Country:{
ID:f4e819b2-5c1a-43f9-bfa1-fe56b6ee173e
Name:Tschechien
Code:CZ
}
SkyScannerId:0xc0004d6a90
IATA:0xc0004d6aa0
Latitude:0xc0004d6ac0
Longitude:0xc0004d6ad0
}
]
请注意**输出中的 Country 字段**。在实际输出中,所有的城市都有相同的国家。我认为这与指针有关。
当我从 Country 中**移除指针**(所以 `*Country` 变成了没有 `*` 的 `Country`)时,我得到了期望的输出。但是我想要在指针(`*Country`)的情况下得到相同的输出。
另外,请不要关注其他字段中打印出的值。我的主要关注点是 Country 字段。
有什么办法可以修复这个问题吗?
P.S. 我知道我也可以在 Country 字段中不使用指针,但我只是想知道是否有任何可能性可以这样做。
<details>
<summary>英文:</summary>
Suppose you have database models as follows:
package storage
type Country struct {
ID string json:"id" gorm:"type:uuid"
Name string json:"name"
Code string json:"code"
}
type City struct {
ID string json:"id" gorm:"type:uuid"
Name string json:"name"
Code *string json:"code"
CountryId string json:"country_id"
Country *Country json:"country" gorm:"references:ID"
IATA *string json:"iata"
Latitude *string json:"latitude"
Longitude *string json:"longitude"
}
The city should have a pointer to a Country model to make it easier to understand whether Country has been joined (in sql) or not (e.g. ```if city.Country == nil {panic("for whatever reason")}``` )
**The problem appears when I try to get the list of all cities:**
package example
var cities []storage.City
tx.Joins("Country").Find(&cities)
Here, all the cities have been fetched from DB nicely, but the **countries became the same in all the cities.**
EXPECTED OUTPUT
[
{
ID:51e415ab-4301-4268-9345-deed6b1d72f6
Name:Bergen
Code:0xc0004d6ec0
CountryId:0bd3890c-b6b7-4b27-8071-55c8f64562bb
Country:{
ID:0bd3890c-b6b7-4b27-8071-55c8f64562bb
Name:Norwegen
Code:NO
}
SkyScannerId:0xc0004d6ee0
IATA:0xc0004d6ef0
Latitude:0xc0004d6f00
Longitude:0xc0004d6f10
},
{
ID:2468c7f0-0275-4bff-8b7e-4e87bfa63604
Name:Banská Bystrica
Code:0xc0004d6bc0
CountryId:00ba76d3-9591-4d45-a39d-f554375d790f
Country: {
ID:00ba76d3-9591-4d45-a39d-f554375d790f
Name:Slovakei
Code:SK
}
SkyScannerId:<nil>
IATA:<nil>
Latitude:0xc0004d6c00
Longitude:0xc0004d6c10
},
{
ID:75501988-3c80-4ef9-8081-73d20cbcc29b
Name:Prag
Code:0xc0004d6a60
CountryId:f4e819b2-5c1a-43f9-bfa1-fe56b6ee173e
Country:{
ID:f4e819b2-5c1a-43f9-bfa1-fe56b6ee173e
Name:Tschechien
Code:CZ
}
SkyScannerId:0xc0004d6a90
IATA:0xc0004d6aa0
Latitude:0xc0004d6ac0
Longitude:0xc0004d6ad0
}
]
ACTUAL OUTPUT:
[
{
ID:51e415ab-4301-4268-9345-deed6b1d72f6
Name:Bergen
Code:0xc0004d6ec0
CountryId:0bd3890c-b6b7-4b27-8071-55c8f64562bb
Country:{
ID:f4e819b2-5c1a-43f9-bfa1-fe56b6ee173e
Name:Tschechien
Code:CZ
}
SkyScannerId:0xc0004d6ee0
IATA:0xc0004d6ef0
Latitude:0xc0004d6f00
Longitude:0xc0004d6f10
},
{
ID:2468c7f0-0275-4bff-8b7e-4e87bfa63604
Name:Banská Bystrica
Code:0xc0004d6bc0
CountryId:00ba76d3-9591-4d45-a39d-f554375d790f
Country:{
ID:f4e819b2-5c1a-43f9-bfa1-fe56b6ee173e
Name:Tschechien
Code:CZ
}
SkyScannerId:<nil>
IATA:<nil>
Latitude:0xc0004d6c00
Longitude:0xc0004d6c10
},
{
ID:75501988-3c80-4ef9-8081-73d20cbcc29b
Name:Prag
Code:0xc0004d6a60
CountryId:f4e819b2-5c1a-43f9-bfa1-fe56b6ee173e
Country:{
ID:f4e819b2-5c1a-43f9-bfa1-fe56b6ee173e
Name:Tschechien
Code:CZ
}
SkyScannerId:0xc0004d6a90
IATA:0xc0004d6aa0
Latitude:0xc0004d6ac0
Longitude:0xc0004d6ad0
}
]
Please pay attention to **Country field of the outputs**. In the ACTUAL OUTPUT all the cities have the same country. I think this has something to do with the pointer.
I **got** EXPECTED OUTPUT when I **removed** **the** **pointer** from Country (so ```*Country``` became ```Country``` without ```*```). But I would like to get the same output with the pointer (```*Country```).
Also, please do not pay attention to the values printed out in other fields. My main focus is the Country field.
Any ideas how to fix it ?
P.S. I know that i can survive without using the pointers too in the Country field, but I just want to know if there are any possibilities to do that.
</details>
# 答案1
**得分**: 1
尝试将countryId也作为指针传递。
像这样:
CountryId *string `json:"country_id"`
实际上,我尝试使用你的代码示例复制错误,但它运行良好。
<details>
<summary>英文:</summary>
Try to put countryId as a pointer too.
Like this
CountryId *string `json:"country_id"`
Actually I tried to replicate the error with you code example, but it's working well.
</details>
# 答案2
**得分**: 0
我注意到这是 ```gorm-v1.23.6``` 的行为。切换回 ```gorm-v1.23.5``` 解决了这个问题。
<details>
<summary>英文:</summary>
I have noticed that this is the behavior with ```gorm-v1.23.6```. Switching back to ```gorm-v1.23.5``` solved the problem.
</details>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论