英文:
Accessing values from postgres jsonb column in Golang
问题
我正在从Postgres中获取一个jsonb列,其值类似于
{
"a": 123,
"b": "some str",
"c": {"d": 23},
"e": {"f":34, "g": 434}
}
如何访问键a、b、d、f、g?谢谢
编辑:获取jsonb列"vars":
type Msg struct{
Id int
Vars map[string]interface{}
}
queryToGetD := "select id, vars from msg_table"
if rows, errRow := db.Query(queryToGetD); errRow != nil {
return nil, fmt.Errorf("error while getting data \nquery %s \nerror %s", queryToGetD, err)
} else {
func (){
defer rows.Close()
for rows.Next(){
var msg Msg
var vars string
if err := rows.Scan(&msg.Id, &vars); err != nil{
// 处理错误
continue
}else{
if err := json.Unmarshal([]byte(vars), &msg.Vars); err != nil {
// 处理错误
continue
}
// 将msg添加到所需的切片中
}
}
}
}
英文:
I am getting a jsonb column from postgres which has value something like
{
"a": 123,
"b": "some str",
"c": {"d": 23},
"e": {"f":34, "g", 434}
}
How can i access keys a, b, d, f, g? Thanks
EDIT: getting the jsonb column "vars":
type Msg struct{
Id int
Vars map[string]interface{}
}
queryToGetD := "select id, vars from msg_table"
if rows, errRow := db.Query(queryToGetD); errRow != nil {
return nil, fmt.Errorf("error while getting data \nquery %s \nerror %s", queryToGetD, err)
} else {
func (){
defer rows.Close()
for rows.Next(){
var msg Msg
var vars string
if err := rows.Scan(&msg.Id, &vars); err != nil{
// handle error
continue
}else{
if err := json.Unmarshal([]byte(vars), &msg.Vars); err != nil {
// handle error
continue
}
// Add msg to the needed slice
}
}
}
}
答案1
得分: 2
对于变量a和b,你可以使用msg.Vars["a"]
和msg.Vars["b"]
来访问它们的值。对于d、f和g,你需要首先访问它们的父级,就像访问a和b一样。然后,你需要对访问结果进行类型断言,将其断言为map[string]interface{}
类型,然后通过类型断言的结果访问所需的字段。
fmt.Println(msg.Vars["a"]) // 访问a
fmt.Println(msg.Vars["b"]) // 访问b
c := msg.Vars["c"].(map[string]interface{}) // 访问c并将其类型断言为map[string]interface{}
fmt.Println(c["d"]) // 然后访问d
https://go.dev/play/p/oZERUsL2EUY
或者使用与JSON匹配的结构体,然后你可以使用选择器表达式访问字段。
type Vars struct {
A int `json:"a"`
B string `json:"b"`
C struct {
D int `json:"d"`
} `json:"c"`
E struct {
F int `json:"f"`
G int `json:"g"`
} `json:"e"`
}
// ...
fmt.Println(msg.Vars.A)
fmt.Println(msg.Vars.B)
fmt.Println(msg.Vars.C.D)
fmt.Println(msg.Vars.E.F)
fmt.Println(msg.Vars.E.G)
https://go.dev/play/p/6ur78SNB_bL
英文:
For a and b you can do msg.Vars["a"]
and msg.Vars["b"]
respectively to access those values. For d, f, and g you need to first access their parents just like you would access a and b. Then you need to type-assert the result of that access to the map[string]interface{}
type and then access the desired fields through the result of the type assertion.
fmt.Println(msg.Vars["a"]) // access a
fmt.Println(msg.Vars["b"]) // access b
c := msg.Vars["c"].(map[string]interface{}) // access c and type-assert as map[string]interface{}
fmt.Println(c["d"]) // then access d
https://go.dev/play/p/oZERUsL2EUY
Or use a struct that matches the json, then you can access the fields with the selector expression
type Vars struct {
A int `json:"a"`
B string `json:"b"`
C struct {
D int `json:"d"`
} `json:"c"`
E struct {
F int `json:"f"`
G int `json:"g"`
} `json:"e"`
}
// ...
fmt.Println(msg.Vars.A)
fmt.Println(msg.Vars.B)
fmt.Println(msg.Vars.C.D)
fmt.Println(msg.Vars.E.F)
fmt.Println(msg.Vars.E.G)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论