3

我正在尝试从一对多关系预加载数据,但我总是收到“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,尽管不是明确的(也不能通过指定它来工作)我在这里理解有什么问题吗?

4

2 回答 2

5

APIKeys列为结构字段名称,但尝试ApiKeys用作 FK。

.Preload("ApiKeys")
// Should be
.Preload("APIKeys")

或者,如果您想ApiKeys用作外键,请使用 Gorm 结构标记来执行此操作。

完整的工作示例

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)
}
于 2021-03-26T09:20:53.893 回答
0

解决了吗?我也遇到了同样的问题。<br />当我尝试从一对多关系中预加载数据时,
报告:架构教师信息不支持的关系

github.com/99designs/gqlgen v0.13.0

gorm.io/gorm v1.21.8

模型根:

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

}

解决

于 2021-04-24T12:31:20.983 回答