首页 > 解决方案 > GORM: Create() 具有不同的输入和输出结构

问题描述

在 GORM 中是否可以将 Create() 一个Struct A 作为输入并将结果存储在 Struct B 中

我没有在文档或互联网上找到任何合适的东西。

背景如下:我让 Postgres 创建字段 id、createdAt 和 updatedAt - 因此它们不应该是输入结构 A 的一部分(类似于 DTO/DAO)。

然而,在 Create() 的结果中,这些字段是存在的——因此它们应该被解析为包含表的所有字段的结构 B。

如果没有明确设置 id、createdAt 和 updatedAt 会出现问题:

Go 会根据数据类型(0、nil 等)初始化未使用默认值显式定义的结构字段。对于 UUIDv4 类型的 id,其值为 then 00000000-0000-0000-0000000000

显然,这个传递的值会覆盖gen_random_uuid()id 列的 Postgres 值。

一旦这工作正常,就会发生重复键错误。另一方面,createdAt 和 updatedAt 似乎是由 Postgres 正确生成的,尽管我也在那里找到了 Go 的默认值。

谢谢!

PS:当然,我可以简单地创建一个UUID并把它交给数据库,但我主要感兴趣的是我的意图是否可以用GORM实现。

标签: go-gorm

解决方案


您不需要两个单独的结构,您可以使用您的模型来插入/获取。一种方法是嵌入gorm.Model,它将嵌入

// gorm.Model definition
type Model struct {
  ID        uint           `gorm:"primaryKey"`
  CreatedAt time.Time
  UpdatedAt time.Time
  DeletedAt gorm.DeletedAt `gorm:"index"`
}

嵌入到用户结构中。

type User struct {
  gorm.Model
  Name string
  Age  int
}
// equals
type User struct {
  ID        uint           `gorm:"primaryKey"`
  CreatedAt time.Time
  UpdatedAt time.Time
  DeletedAt gorm.DeletedAt `gorm:"index"`
  Name string
  Age  int
}

现在创建记录

user := User{Name: "randomname", Age: 18}

result := db.Create(&user) // pass pointer of data to Create

user.ID             // returns inserted data's primary key
user.CreatedAt      // returns inserted data's created at key
user.UpdatedAt      // returns inserted data's updated at key

嵌入gorm.Model是可选的,您可以嵌入它或直接将字段添加到结构中,或者您可以创建自己的结构来嵌入。

即使在插入时这些字段 [updatedAt, createdAt] 是空的或不是输入结构的一部分,结果也会返回数据库中的任何内容。如果createdAtorupdatedAt是由 postgres 和 nonEmpty 创建的,它将被返回。

更新:- 我们可以使用默认值

type HasUuidPkey struct {
        ID        uuid.UUID `gorm:"primaryKey;default:gen_random_uuid()"`
        Name      string
        CreatedAt time.Time
}

游乐场示例


推荐阅读