gorm 中不受支持的关系
Unsupported relations in gorm
我正在尝试从一对多关系中预加载数据,但我总是收到“ApiKeys:模式客户端不支持的关系”错误。 (结构是指针的原因是因为我使用的是 gqlgen,这是默认配置)
type Client struct {
// Client ID
ID int `json:"id"`
UserName string `json:"userName"`
// Client login hashed password
Password string `json:"password"`
// ApiKeys
APIKeys []*APIKey `json:"apiKeys"`
}
type APIKey struct {
// ApiKey Index
ID int `json:"id"`
// ApiKey Value
Key string `json:"key"`
// ApiKey Client Relation
ClientID int `json:"clientID"`
// ApiKey Client Info
Client *Client `json:"client"`
}
这是调用ApiKeys Preload的函数
func (r *queryResolver) ClientInfoResolver(username string, password string) (*model.Client, error) {
var clients []*model.Client
var client *model.Client
query := r.Resolver.DB
query = query.Where("user_name = ? AND password = ?", username, password).Preload("ApiKeys").Find(&clients)
if query.Error != nil {
return client, query.Error
}
return clients[0], nil
}
根据 gorm 的文档,我了解到该关系的外键是 ClientID,尽管它不是显式的(通过指定它也不起作用)我理解错了吗?
您将 APIKeys
列为结构字段名称,但尝试使用 ApiKeys
作为 FK。
.Preload("ApiKeys")
// Should be
.Preload("APIKeys")
或者,如果您想使用 ApiKeys
作为外键,use a Gorm struct tag to do this.
完整的工作示例
package main
import (
"fmt"
"gorm.io/driver/sqlite"
"gorm.io/gorm"
)
type Client struct {
// ApiKey Index
ID int `json:"id"`
UserName string `json:"userName"`
// Client login hashed password
Password string `json:"password"`
// ApiKeys
APIKeys []*APIKey `json:"apiKeys"`
}
type APIKey struct {
// ApiKey Index
ID int `json:"id"`
// ApiKey Value
Key string `json:"key"`
// ApiKey Client Relation
ClientID int `json:"clientID"`
// ApiKey Client Info
Client *Client `json:"client"`
}
func main() {
db, err := gorm.Open(sqlite.Open("many2many.db"), &gorm.Config{})
if err != nil {
panic("failed to connect database")
}
// Migrate the schema
err = db.AutoMigrate(&APIKey{}, &Client{})
if err != nil {
fmt.Print(err)
}
clientOne := Client{
UserName: "Client One",
}
db.Create(&clientOne)
apiKeyOne := APIKey{
Key:"one",
Client: &clientOne,
}
apiKeyTwo := APIKey{
Key:"two",
Client: &clientOne,
}
db.Create(&apiKeyOne)
db.Create(&apiKeyTwo)
// Fetch from DB
fetchedClient := Client{}
db.Debug().Preload("APIKeys").Find(&fetchedClient, clientOne.ID)
fmt.Println(fetchedClient)
db.Delete(&clientOne)
db.Delete(&apiKeyOne)
db.Delete(&apiKeyTwo)
}
解决了吗?我也遇到了同样的问题。
当我尝试从一对多关系中预加载数据时,
report:unsupported 架构 TeacherInfo 的关系
github.com/99designs/gqlgen v0.13.0
gorm.io/gorm v1.21.8
models_gen:
func (TeacherInfo) TableName() string {
return "teacher_info"
}
type TeacherInfo struct {
ID int `json:"id" gorm:"primaryKey"`
Name string `json:"name"`
Avatar string `json:"avatar" `
Info string `json:"info" `
Score float64 `json:"score" `
Role int `json:"role" `
TeacherScore []*TeacherScore `json:"teacherScore" gorm:"foreignkey:TID; references:ID"`
}
func (TeacherScore) TableName() string {
return "teacher_score"
}
type TeacherScore struct {
ID int `json:"id" `
TID int `json:"t_id" `
Comment string `json:"comment" `
UID int `json:"u_id" `
Score float64 `json:"score" `
}
解析器:
func (r *queryResolver) TeacherScore(ctx context.Context, id int) (*model.TeacherInfo, error) {
var teacherInfo model.TeacherInfo
wrong: dao.DB.Debug().Preload("teacher_score").First(&teacherInfo)
right: here is teacherInfo's cloume TeacherScore
dao.DB.Debug().Preload("TeacherScore").First(&teacherInfo)
return &teacherInfo, nil
}
已解决
我正在尝试从一对多关系中预加载数据,但我总是收到“ApiKeys:模式客户端不支持的关系”错误。 (结构是指针的原因是因为我使用的是 gqlgen,这是默认配置)
type Client struct {
// Client ID
ID int `json:"id"`
UserName string `json:"userName"`
// Client login hashed password
Password string `json:"password"`
// ApiKeys
APIKeys []*APIKey `json:"apiKeys"`
}
type APIKey struct {
// ApiKey Index
ID int `json:"id"`
// ApiKey Value
Key string `json:"key"`
// ApiKey Client Relation
ClientID int `json:"clientID"`
// ApiKey Client Info
Client *Client `json:"client"`
}
这是调用ApiKeys Preload的函数
func (r *queryResolver) ClientInfoResolver(username string, password string) (*model.Client, error) {
var clients []*model.Client
var client *model.Client
query := r.Resolver.DB
query = query.Where("user_name = ? AND password = ?", username, password).Preload("ApiKeys").Find(&clients)
if query.Error != nil {
return client, query.Error
}
return clients[0], nil
}
根据 gorm 的文档,我了解到该关系的外键是 ClientID,尽管它不是显式的(通过指定它也不起作用)我理解错了吗?
您将 APIKeys
列为结构字段名称,但尝试使用 ApiKeys
作为 FK。
.Preload("ApiKeys")
// Should be
.Preload("APIKeys")
或者,如果您想使用 ApiKeys
作为外键,use a Gorm struct tag to do this.
完整的工作示例
package main
import (
"fmt"
"gorm.io/driver/sqlite"
"gorm.io/gorm"
)
type Client struct {
// ApiKey Index
ID int `json:"id"`
UserName string `json:"userName"`
// Client login hashed password
Password string `json:"password"`
// ApiKeys
APIKeys []*APIKey `json:"apiKeys"`
}
type APIKey struct {
// ApiKey Index
ID int `json:"id"`
// ApiKey Value
Key string `json:"key"`
// ApiKey Client Relation
ClientID int `json:"clientID"`
// ApiKey Client Info
Client *Client `json:"client"`
}
func main() {
db, err := gorm.Open(sqlite.Open("many2many.db"), &gorm.Config{})
if err != nil {
panic("failed to connect database")
}
// Migrate the schema
err = db.AutoMigrate(&APIKey{}, &Client{})
if err != nil {
fmt.Print(err)
}
clientOne := Client{
UserName: "Client One",
}
db.Create(&clientOne)
apiKeyOne := APIKey{
Key:"one",
Client: &clientOne,
}
apiKeyTwo := APIKey{
Key:"two",
Client: &clientOne,
}
db.Create(&apiKeyOne)
db.Create(&apiKeyTwo)
// Fetch from DB
fetchedClient := Client{}
db.Debug().Preload("APIKeys").Find(&fetchedClient, clientOne.ID)
fmt.Println(fetchedClient)
db.Delete(&clientOne)
db.Delete(&apiKeyOne)
db.Delete(&apiKeyTwo)
}
解决了吗?我也遇到了同样的问题。
当我尝试从一对多关系中预加载数据时,
report:unsupported 架构 TeacherInfo 的关系
github.com/99designs/gqlgen v0.13.0
gorm.io/gorm v1.21.8
models_gen:
func (TeacherInfo) TableName() string {
return "teacher_info"
}
type TeacherInfo struct {
ID int `json:"id" gorm:"primaryKey"`
Name string `json:"name"`
Avatar string `json:"avatar" `
Info string `json:"info" `
Score float64 `json:"score" `
Role int `json:"role" `
TeacherScore []*TeacherScore `json:"teacherScore" gorm:"foreignkey:TID; references:ID"`
}
func (TeacherScore) TableName() string {
return "teacher_score"
}
type TeacherScore struct {
ID int `json:"id" `
TID int `json:"t_id" `
Comment string `json:"comment" `
UID int `json:"u_id" `
Score float64 `json:"score" `
}
解析器:
func (r *queryResolver) TeacherScore(ctx context.Context, id int) (*model.TeacherInfo, error) {
var teacherInfo model.TeacherInfo
wrong: dao.DB.Debug().Preload("teacher_score").First(&teacherInfo)
right: here is teacherInfo's cloume TeacherScore
dao.DB.Debug().Preload("TeacherScore").First(&teacherInfo)
return &teacherInfo, nil
}
已解决