【问题标题】:GORM: Create() with different Input and Output StructsGORM: Create() 具有不同的输入和输出结构
【发布时间】:2021-10-20 23:04:42
【问题描述】:

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

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

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

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

id、createdAt 和 updatedAt 没有明确设置的问题:

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

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

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

谢谢!

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

【问题讨论】:

    标签: go-gorm


    【解决方案1】:

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

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

    Embedding 进入用户结构。

    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] 是空的或不是输入结构的一部分,结果也会返回数据库中的任何内容。如果 createdAtupdatedAt 由 postgres 创建且 nonEmpty 将被返回。

    更新 :- 我们可以使用default values

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

    游乐场example

    【讨论】:

    • 感谢您的帮助!这是文档中的标准方法,但如果您没有为 id 设置 UUID,它在我的特定情况下不起作用。我已经相应地扩展了我上面的问题,并从文档中解释了程序的问题。
    猜你喜欢
    • 2021-04-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-21
    • 1970-01-01
    • 2017-03-03
    • 2011-05-01
    相关资源
    最近更新 更多