Go 编组空映射[string]接口{}会导致;空";而不是零
我有一个问题,如果我尝试执行以下操作,Go会将“null”插入到PostgreSQL数据库的jsonb列中,并且structs属性(在这种情况下是map[string]interface{}类型)为空:Go 编组空映射[string]接口{}会导致;空";而不是零,go,Go,我有一个问题,如果我尝试执行以下操作,Go会将“null”插入到PostgreSQL数据库的jsonb列中,并且structs属性(在这种情况下是map[string]interface{}类型)为空: accessMembers, _ := json.Marshal(c.AccessMembers) 执行测试打印时,输出的值与存储到数据库中的值相同: fmt.Println(string(accessMembers)) // equals the string "null" 问题是我需要它
accessMembers, _ := json.Marshal(c.AccessMembers)
执行测试打印时,输出的值与存储到数据库中的值相同:
fmt.Println(string(accessMembers)) // equals the string "null"
问题是我需要它是-nil(不是字符串,而是Golang nil),所以当我在下面的Exec函数中使用它时:
sqlStr := `UPDATE my_table SET access_members=$1 WHERE id=$2;`
_, err := db.Exec(sqlStr, accessMembers, c.Id)
它应该与doing:
_, err := db.Exec(sqlStr, nil, c.Id)
var accessMembers interface{} = nil
if c.AccessMembers != nil {
j, _ := json.Marshal(c.AccessMembers)
accessMembers = j
}
我尝试了很多不同的解决办法,我认为这些办法必须奏效,但没有奏效
例如
这将导致以下错误:“pq:json类型的输入语法无效”
我不明白为什么这与在Exec functions参数中显式写入nil不同,因为[]字节显然必须是nil,对吗
我做错了什么?以下是我希望它能起作用的方式:
回答:
_, err := db.Exec(sqlStr, nil, c.Id)
var accessMembers interface{} = nil
if c.AccessMembers != nil {
j, _ := json.Marshal(c.AccessMembers)
accessMembers = j
}
感谢thwd提供了基本的解决方案,并指出了数据库驱动程序如何以不同的方式封送nil,建议使用接口{}而不是[]字节
感谢DonSeba提醒我在使用资源封送、字符串转换和比较之前检查struct字段是否存在,这应该更昂贵。您还没有初始化
AccessMembers
在决定封送该值之前,应检查该值是否存在
if c.AccessMembers == nil {
c.AccessMembers = make(map[string]interface{})
}
如果您执行上述操作,则结果如下:
accessMembers, err := json.Marshal(c.AccessMembers)
将是一个有效的空json值{}
,用于存储到数据库中并在以后检索该值
更新:
这里对“NULL”值进行了一些讨论:
我不明白为什么这与在Exec functions参数中显式写入nil不同,因为[]字节显然必须是nil,对吗
nil
有一个类型。对于类型map[string]interface{}
或[]byte
的数据库驱动程序封送nil
的方式不同于interface{}
(这是db.Exec
的第二个参数的类型)。您应该能够做到:
var i interface{} = nil
j, _ := json.Marshal(c.AccessMembers)
if string(j) != "null" {
i = j
}
sqlStr := `UPDATE content SET access_members=$1 WHERE id=$2;`
_, err := db.Exec(sqlStr, i, c.Id)
谢谢你的建议。它确实解决了错误,但插入的值仍然是我的jsonb列中的空映射“{}”,在这里,我需要将映射封送为NULL,就像我在Exec函数中直接输入-nil-作为参数一样。我已经阅读了该链接,但在我看来,该线程中没有真正的解决方案:/json.Marshal()无法“查看|访问”c.AccessMembers,它按其工作方式返回“NULL”。。。