Gorm relationship error: need to define a valid foreign key for relations or it need to implement the Valuer/Scanner interface
Gorm relationship error: need to define a valid foreign key for relations or it need to implement the Valuer/Scanner interface
我正在解决使用 Gorm 时出现的问题。我的 sqlite3 数据库和 Go 数据模型的一切都很好,但是当我在构建环境中遇到一些依赖关系的问题时,我尝试了 copying/deleting vendor 文件夹中的一些包,重新'go get' 直到我的构建工作......但是现在当我在我自己的机器上编译和运行时,我遇到了以前从未遇到过的问题。
当我尝试这样的事情时(已检查 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"`
}
所以问题是,有人知道是什么原因造成的吗?更重要的是,您对如何解决这个问题有什么建议吗?
在我看来,您为 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"`
}
我正在解决使用 Gorm 时出现的问题。我的 sqlite3 数据库和 Go 数据模型的一切都很好,但是当我在构建环境中遇到一些依赖关系的问题时,我尝试了 copying/deleting vendor 文件夹中的一些包,重新'go get' 直到我的构建工作......但是现在当我在我自己的机器上编译和运行时,我遇到了以前从未遇到过的问题。
当我尝试这样的事情时(已检查 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"`
}
所以问题是,有人知道是什么原因造成的吗?更重要的是,您对如何解决这个问题有什么建议吗?
在我看来,您为 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"`
}