【问题标题】:ERROR: missing FROM-clause entry for table when using GORM错误:使用 GORM 时缺少表的 FROM 子句条目
【发布时间】:2022-12-22 19:48:35
【问题描述】:

这些是我数据库中的表

CREATE TABLE vehicles
(
    id          VARCHAR PRIMARY KEY,
    make        VARCHAR NOT NULL,
    model       VARCHAR NOT NULL,
)

CREATE TABLE collisions
(
    id            VARCHAR PRIMARY KEY,
    longitude     FLOAT NOT NULL,
    latitude      FLOAT NOT NULL,
)

CREATE TABLE vehicle_collisions
(   
    vehicle_id    VARCHAR NOT NULL,
    collision_id  VARCHAR NOT NULL,
    PRIMARY KEY (vehicle_id, collision_id)
)

所以我需要找到具有特定 collision_id 的车辆列表。我正在使用 gorm 。

我试图以某种方式实现它

    var vehicles []entities.Vehicles
    err := r.db.Joins("JOIN vehicles as vh on vh.id=vehicle_collisions.vehicle_id").Where("vehicle_collisions.collision_id=?",
        id).Find(&vehicles).Error
    if err != nil {
        fmt.Println(err)
    }

但它让我出错

 ERROR: missing FROM-clause entry for table "vehicle_collisions" (SQLSTATE 42P01)

任何帮助将不胜感激。

【问题讨论】:

  • vehicles[]entities.Vehicles 类型,它可能对应于 vehicles 表。这意味着,如果您将 vehicles 传递给 Find,它将生成一个 SELECT * FROM vehicles 并向其添加一个连接,例如 JOIN vehicles ... 没有意义,对吗?这也是它抱怨vehicle_collisions 没有FROM clause 的原因。所以只需翻转 JOIN 子句中的表,你就可以开始了:go.dev/play/p/-Tv71Setmbl
  • 谢谢 @mkopriva 准确指出了我的错误,但现在它在 Find(&vehicles).Error 上出现恐慌,消息为 `panic serving [::1]:54547: reflect: call of reflect.Value.Field on slice Value` 。
  • 你能说明 entities.Vehicles 的类型是如何定义的吗?它是一个结构吗?或者它是一片?将声明添加到问题中。
  • 没关系,我定义数组并创建数组的数组修复它是一个错误。再次非常感谢您的帮助。最后一件事,如果你可以分享一些书籍或参考资料来为像我这样的 golang 新手学习 Go。
  • 我没有读过任何 Go 书籍,只读过官方的language specEffective Go指南和我需要使用的任何包的官方documentation。我的一本书听到好的是this one(但同样,我自己还没有读过)。

标签: postgresql go go-gorm


【解决方案1】:

谢谢 mkopriva 指出 当您将 &vehicles(即 []entities.Vehicles)传递给 Find 时,生成的查询如下所示:

SELECT
  *
FROM
  vehicles
JOIN
  vehicles vh
ON vh.id = vehicle_collisions.vehicle_id
WHERE vehicle_collisions.collision_id=1

解决问题不正确将查询修改为:

err := r.db.
    Joins("JOIN vehicle_collisions AS vc ON vc.vehicle_id=vehicles.id").
    Where("vc.collision_id = ?", id).
    Find(&vehicles).Error

【讨论】:

  • 您好 Chandan,感谢您的回答,但它再次显示相同的错误。
【解决方案2】:

由于问题缺少一些细节,我试图猜测它们。我希望提供的答案与您相关!让我展示我这边的代码:

package main

import (
    "gorm.io/driver/postgres"
    "gorm.io/gorm"

    _ "github.com/lib/pq"
)

type Vehicle struct {
    Id         string
    Make       string
    Model      string
    Collisions []Collision `gorm:"many2many:vehicle_collisions"`
}

type Collision struct {
    Id        string
    Longitude float64
    Latitude  float64
}

func main() {
    dsn := "host=localhost user=postgres password=postgres dbname=postgres port=5432 sslmode=disable"
    db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{})
    if err != nil {
        panic(err)
    }

    db.AutoMigrate(&Vehicle{})
    db.AutoMigrate(&Collision{})

    // add dummy data to the db
    collision := &Collision{"1", 4.4, 4.5}
    db.Create(collision)
    db.Create(&Collision{"2", 1.1, 1.5})
    db.Create(&Vehicle{Id: "1", Make: "ford", Model: "fiesta", Collisions: []Collision{*collision}})
    db.Create(&Vehicle{Id: "2", Make: "fiat", Model: "punto", Collisions: []Collision{*collision}})

    // get all vehicles for collision 1
    var vehicles []Vehicle
    db.Debug().Joins("inner join vehicle_collisions vc on vehicles.id = vc.vehicle_id").Find(&vehicles, "vc.collision_id = ?", "1")
}

代码以结构的定义开始。

请注意字段Collisions 上的 Gorm 注释。

添加一些数据后,查询应该非常简单:我们使用Joins方法从表vehicle_collisions加载数据,在Find方法中我们只过滤掉collision_id等于"1"的记录。
如果这对您有帮助或您需要其他东西,请告诉我!

【讨论】:

    猜你喜欢
    • 2015-11-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-22
    相关资源
    最近更新 更多