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

huangapple go评论71阅读模式
英文:

How to insert NULL value to UUID instead of zeros

问题

我有一个在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')

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

我还注意到在字符串类型中也会发生这种情况,它会插入一个空字符串'',而不是NULL。

我该如何让gorm插入NULL而不是零值/空字符串作为值?

英文:

I have a table in postgres with a UUID field type that must be unique but can be null

with a table & model like this

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

and the go model defined as

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"})

and prints the following sql query to the terminal

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')

it inserted the model into the database with 00000000-0000-0000-0000-000000000000as the key value instead of NULL

I also notice this happen with string type where it inserted an empty string '' instead of NULL

how do i make gorm insert NULL instead of zeros/empty string as the value ?

答案1

得分: 5

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

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:在SQL转换为Go时将null转换为""
  • driver.Valuer(来自sql/driver包):在Go转换为SQL时将""转换为null

不过我没有测试过,所以你需要自己尝试一下。

英文:

Try changing your field's type to a pointer type :

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"`
}

You would obviously have to adapt your go code too (e.g: check if record.Key != nil, access *record.Key instead of record.Key, etc ...)


I think gorm also honors the regular sql interfaces, so you may also try to define a custom type which implements :

  • sql.Scanner to turn null into "" on sql -> go conversions,
  • driver.Valuer (from the sql/driver package) to turn "" to null on go -> sql conversions.

I haven't tested it though, so you would have to try it yourself.

答案2

得分: 0

您正在使用的包在问题中没有指定。如果您正在使用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,  // 类型为uuid.UUID
    Valid: true,
}

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

英文:

The package you are using is not specified in the question. If you are using satori/go.uuid, you can use the NullUUID type:

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"`
}

To set a value:

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

To save null, just save the zero value. Both Scan & Value methods are already defined.

huangapple
  • 本文由 发表于 2022年4月27日 12:28:28
  • 转载请务必保留本文链接:https://go.coder-hub.com/72023281.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定