php小编新一在开发过程中,有时会遇到"无法添加或更新子行 - 外键约束在自引用时失败"的错误。这个错误通常发生在数据库中存在自引用的情况下,比如一个表中的某个字段引用了表中的另一个字段。在这种情况下,如果外键约束没有正确配置,就会导致无法添加或更新子行的错误。接下来,我们将介绍一些解决这个问题的方法。
问题内容
我有一个如下所示的结构:
type category struct {
code *int `gorm:"unique;primarykey;"`
parentcategory *category `gorm:"foreignkey:code"`
}
类别本身可以有一个parentcategory,它也来自类别类型。所以它引用了它自己。 如果它是第一个类别,则它没有父类别。
我有一个包含 4 个类别的数组,如上所述,第一个没有 ab parentcategory。
当一个接一个地保存这些类别时(从第一个没有 parentcategory 开始,我收到这些错误(只需在此处打印前两个):
Error 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`ps_product_service`.`categories`, CONSTRAINT `fk_categories_parent_category` FOREIGN KEY (`code`) REFERENCES `categories` (`code`))
[20.890ms] [rows:0] INSERT INTO `categories` (`code`) VALUES (0) RETURNING `code`
Error when creating category: Error 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`ps_product_service`.`categories`, CONSTRAINT `fk_categories_parent_category` FOREIGN KEY (`code`) REFERENCES `categories` (`code`))&{Code:0x140003c6a00 ParentCategory:}
2023/06/19 21:31:44 Error 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`ps_product_service`.`categories`, CONSTRAINT `fk_categories_parent_category` FOREIGN KEY (`code`) REFERENCES `categories` (`code`))
[7.689ms] [rows:0] INSERT INTO `categories` (`code`) VALUES (99) RETURNING `code`
Error when creating category: Error 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`ps_product_service`.`categories`, CONSTRAINT `fk_categories_parent_category` FOREIGN KEY (`code`) REFERENCES `categories` (`code`))&{Code:0x140003c6a20 ParentCategory:}
我真的不知道我必须在这里做什么。有人可以帮我解决这个问题吗?
解决方法
我应该使用以下代码来管理您的需求:
package main
import (
"fmt"
"github.com/samber/lo"
"gorm.io/driver/postgres"
"gorm.io/gorm"
)
type category struct {
code uint `gorm:"unique;primarykey;"`
parentcategoryid *uint
parentcategory *category `gorm:"foreignkey:parentcategoryid"`
}
func main() {
dsn := "host=localhost port=54322 user=postgres password=postgres dbname=postgres sslmode=disable"
db, err := gorm.open(postgres.open(dsn))
if err != nil {
panic(err)
}
db.automigrate(&category{})
// load dummy data
db.create(&category{
code: 1,
parentcategoryid: nil,
})
db.create(&category{
code: 2,
parentcategoryid: lo.toptr[uint](1),
})
db.create(&category{
code: 3,
parentcategoryid: lo.toptr[uint](2),
})
db.create(&category{
code: 4,
parentcategoryid: lo.toptr[uint](1),
})
// reading logic
var categories []category
if err := db.model(&category{}).find(&categories).error; err != nil {
panic(err)
}
for _, v := range categories {
if v.parentcategoryid == nil {
fmt.printf("id: %v\tparentcategoryid: \n", v.code)
continue
}
fmt.printf("id: %v\tparentcategoryid: %v\n", v.code, *v.parentcategoryid)
}
}
如果我了解了您的需求,您需要有一个引用自身的表格。这就是为什么我以这种方式定义 category
结构。每个类别都有自己的 parentcategoryid
除非该类别没有父级。如果您尝试执行前面的代码,您应该得到如下结果:
id: 1 parentCategoryId:
id: 2 parentCategoryId: 1
id: 3 parentCategoryId: 2
id: 4 parentCategoryId: 1
也许我没有从你的问题中得到什么,如果是这样的话请告诉我,我会更新我的答案,谢谢!
以上就是Gorm:无法添加或更新子行 - 外键约束在自引用时失败的详细内容,更多请关注编程网其它相关文章!