【问题标题】:Gorm relationship error: need to define a valid foreign key for relations or it need to implement the Valuer/Scanner interfaceGorm 关系错误:需要为关系定义一个有效的外键或者需要实现 Valuer/Scanner 接口
【发布时间】:2021-08-07 20:14:27
【问题描述】:

我正在对使用 Gorm 时出现的问题进行故障排除。我的 sqlite3 数据库和 Go 数据模型一切正常,但是当我在构建环境中遇到一些依赖关系问题时,我尝试从供应商文件夹中复制/删除一些包,重新开始直到我让构建工作......但现在当我在自己的机器上编译和运行时,我遇到了以前从未遇到过的问题。

当我尝试这样的事情时(已经检查了 configID 以确保它有一个有效的条目):

    var config models.ConfigurationDescription

    // Find the Configuration
    results := db.Where("id = ?", configID).
        Preload("Location").
        Find(&config)

Gorm 抛出以下错误:

 "invalid field found for struct `models.ConfigurationDescription`'s field Location, need to define a valid foreign key for relations or it need to implement the Valuer/Scanner interface"

这就是我定义数据模型的方式(在依赖混乱之前工作得很好):

package models

type LocationDescription struct {
    ID       int    `json:"locationID"`
    Name     string `json:"name"`
    IsActive bool   `json:"isActive"`
}

func (LocationDescription) TableName() string { return "locations" }

type ConfigurationDescription struct {
    ID         int                 `json:"configurationID"`
    Name       string              `json:"name"`
    IsActive   bool                `json:"isActive"`
    LocationID int                 `json:"-"`
    Location   LocationDescription `json:"location,omitempty" gorm:"foreignKey:ID;references:LocationID"`
}

func (ConfigurationDescription) TableName() string { return "configurations" }

使用此设置针对 sqlite 数据库运行:

CREATE TABLE IF NOT EXISTS locations (
    id           INTEGER PRIMARY KEY AUTOINCREMENT,
    name         TEXT,
    latitude     REAL CHECK (latitude > 0),
    longitude    REAL CHECK (latitude > 0),
    is_active    INTEGER DEFAULT 0
);

CREATE TABLE IF NOT EXISTS configurations (
    id               INTEGER PRIMARY KEY AUTOINCREMENT,
    location_id      INTEGER,
    name             TEXT,
    is_active        INTEGER DEFAULT 0,
    CONSTRAINT location_fk FOREIGN KEY (location_id) REFERENCES locations(id) ON DELETE CASCADE
);

我知道它工作,我没有更改任何代码。而且我看到的一切看起来都遵循文档到 T,所以它就像对依赖项的更新破坏了某些东西是没有意义的,因为它似乎没有任何重大变化...... ..

并且!真正令人兴奋的是,这行得通:

var location models.Location
DB.Where("is_active = ?", true).
        Preload("Configurations").
        Find(&location)

(这些结构体和数据库其实还有很多字段,不过为了简单起见,我把它们删减了)

type Location struct {
    ID             int             `json:"locationID"`
    Name           string          `json:"name"`
    Latitude       null.Float      `json:"latitude,omitempty"`
    Longitude      null.Float      `json:"longitude,omitempty"`
    IsActive       null.Bool       `json:"isActive" gorm:"default:false"`
    Configurations []Configuration `json:"configurations,omitempty" gorm:"foreignKey:LocationID;references:ID"`
}

type Configuration struct {
    ID             int             `json:"configurationID"`
    LocationID     int             `json:"locationID"`
    Name           string          `json:"name"`
    IsActive       null.Bool       `json:"isActive" gorm:"default:false"`
}

所以问题是,有谁知道这可能是什么原因造成的?更重要的是,您对如何解决此问题有什么建议吗?

【问题讨论】:

    标签: sqlite go go-gorm


    【解决方案1】:

    在我看来,您的 LocationDescription 字段的标签方式错误。

    首先,这是一个Belongs-To relationship 模式。

    • foreignKey 应该命名连接到外部实体的模型本地键字段。
    • references 应命名外部实体的主键或唯一键。

    尝试:

    type ConfigurationDescription struct {
        ID         int                 `json:"configurationID"`
        Name       string              `json:"name"`
        IsActive   bool                `json:"isActive"`
        LocationID int                 `json:"-"`
        Location   LocationDescription `json:"location,omitempty" gorm:"foreignKey:LocationID;references:ID"`
    }
    

    【讨论】:

    • 成功了!现在我真的对它最初的工作方式感到困惑,因为自从我开始从事这个项目以来,它的设置方式肯定是相同的。
    • 我在这里很困惑,如果我使用 json 并且需要编组它来构造我应该为“位置”字段设置什么值。因为它显然不会接受 int 因为原始类型是 struct。
    • @HanifNr 如果您要解组 JSON 版本的 ConfigurationDescription,它应该有一个“位置”键,其值是遵循 Location 结构的模式的 JSON 对象,例如 {"id":1,"name":"test",...},让它成功。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-26
    • 1970-01-01
    • 2021-08-01
    • 2013-01-26
    相关资源
    最近更新 更多