【问题标题】:Unable to set foreign key using gorm Postgresql无法使用 gorm Postgresql 设置外键
【发布时间】:2017-10-11 20:53:17
【问题描述】:

我正在使用 jinzhu/gorm 构建 Golang 后端,但在尝试建立两个表之间的关系时遇到了一些麻烦,例如ItemsManufacturers 使用外键。

我正在遵循jinzhu.me/gorm/models 的步骤,但老实说,我发现自己对手动编写表格等更直接的方法感到困惑,例如,使用go pq

item.go

package model

import "github.com/jinzhu/gorm"

type Item struct {
    gorm.Model
    Item         string       `gorm:"primary_key"`
    Manufacturer Manufacturer `gorm:"ForeignKey:Name"`
}

ma​​nufacturer.go

package model

import "github.com/jinzhu/gorm"

type Manufacturer struct {
    gorm.Model
    Name string `gorm:"primary_key"`
}

我没有收到任何错误或警告。检查我的表时,我注意到没有创建相关性。项目没有制造商字段。

到目前为止我尝试了什么:

  • 未明确写入gorm:"ForeignKey:Name",因为Manufacturer 字段已经是Manufacturer
  • 写信gorm:"ForeignKey:Name;AssociationForeignKey:Name"
  • 手动将它们与db.Model(&model.Item{}).Related(&model.Manufacturer{}) 关联
  • 手动将它们与db.Model(&model.Item{}).Related(&model.Manufacturer{}, "Manufacturer") 关联
  • 手动将它们与db.Model("items").Related("manufacturers") 关联。即使模型的名称是单数,它们也会在 Postgresql 上使用此名称创建。

编辑

尝试类似的东西

type Item struct {
    Item             string       `gorm:"primary_key"`
    Manufacturer     Manufacturer
    ManufacturerID   int
}

type Manufacturer struct {
    ID uint
    Name string
}

导致相同的结果。没有创建外键,我可以使用不存在的 Manufacturer 插入新项目。

我做错了什么?我错过了什么吗?

【问题讨论】:

    标签: postgresql go go-gorm


    【解决方案1】:

    你必须这样做:

    type Item struct {
        gorm.Model
        Item         string       `gorm:"primary_key"`
        ManufacturerName string   `sql:"type:varchar REFERENCES manufacturers(name)"`
        Manufacturer Manufacturer `gorm:"ForeignKey:ManufacturerName;AssociationForeignKey:Name`
    }
    

    告诉它 a) 使用 ManufacturerName 作为外键,并且 B) 在另一个表上使用 Name。

    或者你可以这样做:

    type Item struct {
        gorm.Model
        Item         string       `gorm:"primary_key"`
        ManufacturerID uint       `sql:"type:uint REFERENCES manufacturers(id)"`
        Manufacturer Manufacturer `gorm:"ForeignKey:Man;AssociationForeignKey:Name"`
    }
    

    【讨论】:

    • 它不起作用。 ManufacturerName 被创建,但它不是外键。如果您插入带有ManufacturerName = 'test' 的新项目,而Manufacturer 没有test 的任何条目,则不会引发任何错误。此外,使用 PGAdmin,似乎根本没有创建任何外键约束。无论如何,您应该编辑您的答案,将 foriegn 修复为 foreign
    • 看起来 gorm 在实际创建外键时存在一些问题(根据 github.com/jinzhu/gorm/issues/23),但您似乎可以使用 sql 标签来创建实际键 - 您只需要请注意自动迁移的顺序,以便它引用的表已经存在。
    【解决方案2】:

    请试试这个

        type Item struct {
            Item             string       `gorm:"primary_key"`
            Manufacturer     Manufacturer `gorm:"foreignKey:ManufacturerID;references:id"`
            ManufacturerID   int
        }
        
        type Manufacturer struct {
            ID uint
            Name string
        }
    
        DB.AutoMigrate(&Item{},&Manufacturer{})
    
        item := Item{
            Item:         "item",
            Manufacturer: Manufacturer{
                Name:     "name"
            },
        }
        
        DB.Create(&item)
    

    【讨论】:

      【解决方案3】:

      在遵循 gorm 的文档/谷歌搜索/堆栈溢出时,我找不到任何我发现的解决方案。这对我有用:

      我有一个 Call 对象和 TranscriptItem 对象。

      一个呼叫可以有多个转录项,但一个转录项只能有一个呼叫。

      调用对象

      type Call struct {
          gorm.Model
          DialInNumber      string
      }
      

      成绩单对象

      type TranscriptItem struct {
          gorm.Model
          Transcript string
          CallID     uint
      }
      

      我有自动迁移和手动 AddForeignKey 迁移

          db.AutoMigrate(&Call{}, &TranscriptItem{})
          db.Model(&TranscriptItem{}).AddForeignKey("call_id", "calls(id)", "RESTRICT", "RESTRICT")
      

      我更喜欢使用 gorm 文档中概述的机制,但归根结底,我只需要一些可行的东西。

      【讨论】:

      猜你喜欢
      • 2014-12-29
      • 2017-05-08
      • 2020-11-11
      • 2012-06-25
      • 2019-02-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多