英文:
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-000000000000
as 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 turnnull
into""
on sql -> go conversions,driver.Valuer
(from thesql/driver
package) to turn""
tonull
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值,只需保存零值。Scan
和Value
方法已经定义好了。
英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论