Gorm 关系错误:需要为关系定义一个有效的外键或需要实现 Valuer/Scanner 接口 [英] Gorm relationship error: need to define a valid foreign key for relations or it need to implement the Valuer/Scanner interface

查看:280
本文介绍了Gorm 关系错误:需要为关系定义一个有效的外键或需要实现 Valuer/Scanner 接口的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am troubleshooting an issue that just came up while using Gorm. I had everything working great with my sqlite3 database and Go data models, but then when I had some issues with dependencies not 'go get'ing in the build environment, so I tried copying/deleting some packages from the vendor folder, re 'go get'ing until I got the build working... But now when I compile and run in my own machine, Im getting issues I never had before.

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

When I attempt something like this (configID is already checked to ensure it has a valid entry):

    var config models.ConfigurationDescription

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

Gorm 抛出以下错误:

Gorm is throwing the following error:

 "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"

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

This is how I have defined the data models (which were working great prior to the dependency jumble):

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 数据库运行:

Thats being run against a sqlite database with this setup:

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 的文档,因此将依赖项的更新视为破坏了某些内容是没有意义的,因为似乎没有任何破坏性更改.....

I know it was working and I didn't change any of the code. And everything Im seeing looks like it follows the docs to the T, so it doesn't make sense that it would be like an update to the dependency broke something, because it doesn't appear that there has been any breaking changes.....

而且!真正的关键在于它有效:

AND! The real kicker is that this works:

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

(这些结构体和数据库实际上有更多的字段,但为了简单起见,我把它们删减了)

(these structs and the database actually have many more fields, but for simplicity, Ive trimmed them down)

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"`
}

那么问题是,有人知道是什么原因造成的吗?更重要的是,您对如何解决问题有什么建议吗?

So the question is, does anyone know what might be causing this? And more importantly, have any suggestions for how to fix the issue?

推荐答案

在我看来,您在 LocationDescription 字段中设置了错误的标签.

It seems to me that you've got your tags the wrong way around for the LocationDescription field.

首先,这是一个Belongs-To 关系模式.

  • foreignKey 应命名连接到外部实体的模型本地键字段.
  • references 应命名外部实体的主键或唯一键.
  • foreignKey should name the model-local key field that joins to the foreign entity.
  • references should name the foreign entity's primary or unique key.

尝试:

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"`
}

这篇关于Gorm 关系错误:需要为关系定义一个有效的外键或需要实现 Valuer/Scanner 接口的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆