如何将NULL值插入UUID而不是零

5

我在Postgres中有一个带有UUID字段类型的表格,这个字段必须是唯一的,但可以为空。

如果遇到这样的表格和模型:

CREATE TABLE IF NOT EXISTS asdf(
    id bigserial primary key,
    name varchar(255) NOT NULL,
    key uuid unique,
    created_at timestamptz,
    updated_at timestamptz
);

并且go模型定义为

type Asdf struct {
    ID          uint64    `json:"id" gorm:"type:uuid;column:id"`
    Name        string    `json:"name" gorm:"column:name"`
    Key         uuid.UUID `json:"key" gorm:"column:key"`
    CreatedAt   time.Time `json:"created_at" gorm:"column:created_at"`
    UpdatedAt   time.Time `json:"updated_at" gorm:"column:updated_at"`
}

result := db.Connect().Create(asdf.Asdf {ID:123, Name:"This is the name"})

并将以下SQL查询语句输出到终端。

INSERT INTO "asdf" ("id","name","key","created_at","updated_at")
VALUES('123','This is the name','00000000-0000-0000-0000-000000000000','2022-04-27 03:41:49.338','2022-04-27 03:41:49.338')

在将模型插入数据库时,它使用 00000000-0000-0000-0000-000000000000 作为 key 值,而不是 NULL。

我还发现对于字符串类型,它插入了一个空字符串 '' ,而不是 NULL。

如何使gorm插入NULL而不是零值/空字符串?


2
尝试将此字段的类型更改为Key *uuid.UUID。您显然还需要调整您的Go代码。 - LeGEC
1
我认为gorm也支持常规的sql接口,因此您也可以尝试定义一个自定义类型,该类型实现 sql.Scanner(在 sql -> go 转换中将 null 转换为 "")和 driver.Valuer(来自 sql/driver 包,在 go -> sql 转换中将 "" 转换为 null)。不过我还没有测试它,所以您需要自己尝试。 - LeGEC
我已经在类型上添加了星号,它修复了问题。我也尝试将其应用于字符串类型,也起作用了。@LeGEC - ggk
2个回答

6

尝试将您的字段类型更改为指针类型:

type Asdf struct {
    ID          uint64     `json:"id" gorm:"type:uuid;column:id"`
    Name        string     `json:"name" gorm:"column:name"`
    Key         *uuid.UUID `json:"key" gorm:"column:key"`
    CreatedAt   time.Time  `json:"created_at" gorm:"column:created_at"`
    UpdatedAt   time.Time  `json:"updated_at" gorm:"column:updated_at"`
}

显然,您还需要调整您的 Go 代码(例如:检查 record.Key != nil,访问 *record.Key 而不是 record.Key 等等...)


我认为 gorm 也支持常规的 sql 接口,所以您也可以尝试定义一个自定义类型来实现:

  • sql.Scanner,将 null 转换为 sql -> go 的 "",
  • driver.Valuer(来自sql/driver包)将 ""转换为 go -> sql 的null

虽然我没有测试过,所以您需要自己尝试一下。


实现 ScannerValuer 应该可以正常工作。 - TheHippo

1

您提供的问题中未指定使用的软件包。如果您正在使用 satori/go.uuid,您可以使用 NullUUID 类型

type Asdf struct {
    ID          uint64         `json:"id" gorm:"type:uuid;column:id"`
    Name        string         `json:"name" gorm:"column:name"`
    NullableKey uuid.NullUUID `json:"key" gorm:"column:key"`
    CreatedAt   time.Time      `json:"created_at" gorm:"column:created_at"`
    UpdatedAt   time.Time      `json:"updated_at" gorm:"column:updated_at"`
}

设定一个值:

key := uuid.NullUUID{
    Value: id,  // of type uuid.UUID
    Valid: true
}

要保存 null,只需保存零值。 ScanValue 方法已经定义好了。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接