【问题标题】:GORM preload: How to use a custom table nameGORM preload:如何使用自定义表名
【发布时间】:2021-03-12 22:15:23
【问题描述】:

我有一个预加载的 GORM 查询,它工作得很好,因为我将它绑定到一个名为“companies”的结构,它也是相应数据库表的名称:

var companies []Company
db.Preload("Subsidiaries").Joins("LEFT JOIN company_prod ON company_products.company_id = companies.id").Where("company_products.product_id = ?", ID).Find(&companies)

现在我想做一些类似的事情,但将结果绑定到一个没有引用“公司”表的名称的结构:

var companiesFull []CompanyFull
db.Preload("Subsidiaries").Joins("LEFT JOIN company_prod ON company_products.company_id = companies.id").Where("company_products.product_id = ?", ID).Find(&companies)

为了更好的理解,我简化了第二个调用,真正的调用有更多的 JOIN 并返回更多的数据,所以它不能绑定到“公司”结构。

我收到一个错误:

column company_subsidiaries.company_full_id does not exist

对应的SQL查询:

SELECT * FROM "company_subsidiaries" WHERE "company_subsidiaries"."company_full_id" IN (2,1)

没有“company_subsidiaries.company_full_id”,正确的查询应该是:

SELECT * FROM "company_subsidiaries" WHERE "company_subsidiaries"."company_id" IN (2,1)

条件显然是从结果绑定到的结构的名称生成的。有没有办法为这种情况指定一个自定义名称?

我知道Tabler interface technique,但我相信它不适用于 Preload(尝试过,它会更改主查询的表名,但不会更改预加载)。

更新:有关数据库架构和结构的更多信息

数据库架构

TABLE companies
ID Primary key
OTHER FIELDS

TABLE products
ID Primary key
OTHER FIELDS 

TABLE subsidiaries
ID Primary key
OTHER FIELDS

TABLE company_products
ID Primary key
Company_id Foreign key (companies.id)
Product_id Foreign key (products.id)

TABLE company_subsidiaries
ID Primary key
Company_id Foreign key (companies.id)
Subsidiary_id Foreign key (subsidiaries.id)

结构

type Company struct {
    Products     []*Product `json:"products" gorm:"many2many:company_products;"`
    ID           int        `json:"ID,omitempty"`
}

type CompanyFull struct {
    Products     []*Product `json:"products" gorm:"many2many:company_products;"`
    Subsidiaries []*Subsidiary `json:"subsidiaries" gorm:"many2many:company_products;"`
    ID           int        `json:"ID,omitempty"`
}

type Product struct {
    Name     string `json:"name"`
    ID       int    `json:"ID,omitempty"`
}

type Subsidiary struct {
    Name     string `json:"name"`
    ID       int    `json:"ID,omitempty"`
}

生成的 SQL(由 GORM)

SELECT * FROM "company_subsidiaries" WHERE "company_subsidiaries"."company_full_id" IN (2,1)

SELECT * FROM "subsidiaries" WHERE "subsidiaries"."id" IN (NULL)

SELECT companies.*, company_products.*, FROM "companies" LEFT JOIN company_products ON company_products.company_id = companies.id WHERE company_products.product_id = 1

【问题讨论】:

  • 您能否提供更多有关您的数据库架构的信息(不必是完整架构)?鉴于提供的信息,我真的无法理解查询是如何生成的。此外,我们将非常感谢您提供有关结构的更多信息。
  • 刚刚做了。非常感谢您指出缺少的部分!我不想混淆太多,但显然没有提供足够的信息。

标签: sql go go-gorm


【解决方案1】:

似乎在这种情况下要走的路可能是在您的 CompanyFull 模型中自定义关系。使用 joinForeignKey 可以使用以下代码。

type CompanyFull struct {
    Products     []*Product    `json:"products" gorm:"many2many:company_products;joinForeignKey:ID"`
    Subsidiaries []*Subsidiary `json:"subsidiaries" gorm:"many2many:company_subsidiaries;joinForeignKey:ID"`
    ID           int           `json:"ID,omitempty"`
}

func (CompanyFull) TableName() string {
    return "companies"
}

func main(){
...
  result := db.Preload("Subsidiaries").Joins("LEFT JOIN company_products ON company_products.company_id = companies.id").Where("company_products.product_id = ?", ID).Find(&companies)
  if result.Error != nil {
    log.Println(result.Error)
  } else {
    log.Printf("%#v", companies)
  }

有关自定义关系中使用的外键的更多信息,请查看文档https://gorm.io/docs/many_to_many.html#Override-Foreign-Key

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多