Postgres JSONB字段数组追加及空值初始化问题咨询(Go语言)
问题1:初始化新用户时避免forms数组字段为null,默认生成空数组
有两种可选方案,可搭配使用做双层兜底:
- Go端初始化处理:Go的
nil切片序列化JSON时会输出null,而非nil的空切片会输出[]。你可以封装一个空Forms实例构造函数,初始化插入时统一使用该实例:
func NewEmptyForms() Forms { return Forms{ External: []FormExternal{}, Internal: []FormInternal{}, Download: []FormDownloadPurchaseBU{}, Purchase: []FormDownloadPurchaseBU{}, BU: []FormDownloadPurchaseBU{}, } }
- Postgres端兜底:给
darf表的forms字段设置默认值,就算插入时未传该字段也会生成符合要求的空结构:
ALTER TABLE darf ALTER COLUMN forms SET DEFAULT '{"External": [], "Internal": [], "Download": [], "Purchase": [], "BU": []}'::jsonb;
问题2:向JSONB字段的指定数组属性追加元素
核心SQL逻辑
使用jsonb_set函数+||连接运算符实现,同时用COALESCE兼容旧数据中字段为null的场景:
UPDATE darf SET forms = jsonb_set( forms, '{Download}', -- 要修改的数组属性路径,修改其他数组替换此处即可,比如'{Purchase}' COALESCE(forms->'Download', '[]'::jsonb) || jsonb_build_array($1::jsonb) ) WHERE uid = $2;
说明:
COALESCE(forms->'Download', '[]'::jsonb):如果原Download数组是null,先替换为空数组jsonb_build_array($1::jsonb):将传入的单个元素包装为单元素数组,方便和原数组做连接||运算符用于两个jsonb数组合并
对应Go实现
首先给FormDownloadPurchaseBU结构体实现driver.Valuer接口,方便直接作为参数传入SQL:
func (f FormDownloadPurchaseBU) Value() (driver.Value, error) { return json.Marshal(f) }
然后实现更新方法:
func (db DB) InsertOneFormQuery(email string, form form.FormDownloadPurchaseBU) error { updateQuery := ` UPDATE darf SET forms = jsonb_set( forms, '{Download}', COALESCE(forms->'Download', '[]'::jsonb) || jsonb_build_array($1::jsonb) ) WHERE uid = $2` _, err := db.Conn.Exec(updateQuery, form, email) return err }
内容的提问来源于stack exchange,提问作者bo0m3r31337
相关产品推荐
相关产品推荐

