首页 > 解决方案 > GORM 不会根据主键返回正确的记录

问题描述

我是 GO 的新手,我正在将我的 CRUD 应用程序从使用普通 SQL 迁移到 GORM,然后我遇到了基于主键的查询将在匹配源时返回主键和 nil 的问题,而它应该返回值/记录自己,如记录在:https ://gorm.io/docs/query.html#Retrieving-with-primary-key

我期待查询的值

postgres=# SELECT * FROM users WHERE id = 1;
 id | name | age |         created_at         | updated_at | deleted_at | location
----+------+-----+----------------------------+------------+------------+----------
  1 | Rick |  22 | 2020-09-12 11:34:14.366674 |            |            | Toronto
(1 row)

相反,我得到了这个

&{0xc0000c0900 <nil> 1 0xc00009f860 0}
package main

import (
    "fmt"
    "go-postgres/models"
    "log"
    "os"

    "github.com/joho/godotenv"
    "gorm.io/driver/postgres"
    "gorm.io/gorm"
)

type user models.User

func main() {
    var u user
    db := loadDbSecret()
    result := db.First(&u, 1)

    fmt.Println(result)

}

func loadDbSecret() *gorm.DB {
    err := godotenv.Load(".env")

    if err != nil {
        log.Fatalf("Error loading .env file")
    }

    db, err := gorm.Open(postgres.Open(os.Getenv("POSTGRES_URL")), &gorm.Config{})

    if err != nil {
        panic(err)
    }

    return db
}

谢谢!

标签: postgresqlgocrud

解决方案


您可以阅读有关DB.First的godoc

关于 godoc 的 DB.First 文档的屏幕截图

注意2件事:

  1. 第一个参数out确实是给你输出查询结果的。
  2. 返回值是数据库实例*DB,实际上不是查询结果。

您还可以阅读有关Query的官方网站:

检索单个对象

GORM 提供了 First, Take, Last 方法从数据库中检索单个对象,它在查询数据库时添加了 LIMIT 1 条件,如果没有找到记录将返回错误 ErrRecordNotFound。

// Get the first record ordered by primary key
db.First(&user)
// SELECT * FROM users ORDER BY id LIMIT 1;

// Get one record, no specified order
db.Take(&user)
// SELECT * FROM users LIMIT 1;

// Get last record, order by primary key desc
db.Last(&user)
// SELECT * FROM users ORDER BY id DESC LIMIT 1;

result := db.First(&user)
result.RowsAffected // returns found records count
result.Error        // returns error

// check error ErrRecordNotFound
errors.Is(result.Error, gorm.ErrRecordNotFound)

简而言之,您应该从变量u而不是result.

func main() {
    var u user
    db := loadDbSecret()
    result := db.First(&u, 1)

    fmt.Printf("%v\n", u)
}

推荐阅读