lib/pq支持hstore
,正如它所说的 mkopriva你可以在这里找到信息。但它可能需要一些澄清或更好的例子。
首先,Hstore
在这个驱动程序中有一个包含映射的结构:
type Hstore struct {
Map map[string]sql.NullString
}
所以,如果你想使用那个映射,你首先需要初始化它:
h := hstore.Hstore{}
h.Map = make(map[string]sql.NullString)
然后,您可以使用它,但考虑到地图的形式为[string]sql.NullString
,您需要将值字段转换为sql.NullString
(可为空的字符串,golang 中的默认字符串不可为空。)可以编写一个函数来完成这项工作:
//ToNullString invalidates a sql.NullString if empty, validates if not empty
func ToNullString(s string) sql.NullString {
return sql.NullString{String: s, Valid: s != ""}
}
现在,您可以执行以下操作:
data := hstore.Hstore{}
data.Map["data"] = ToNullString("data")
_, err = db.Exec(`INSERT INTO table(id, my_field) VALUES ($1, $2)`, data, id)
然后您可以更新执行此操作的 hstore 的值:
data.Map["data"] = ToNullString("dat")
_, err := postgresConn.Exec(`UPDATE table SET my_field = my_field || $1 WHERE id = $2`, data, id)
注意,使用 update 会更新 Hstore 中的 map,也就是说如果你只改变 value 部分,它会更新 value;但是如果您更改键和值,它将在您的 hstore 中添加一对新的 (key, value) 而不是替换旧的。
为了澄清一点,我放了一个示例代码来测试它是如何工作的,这段代码应该与你的参数一起工作,我只是为了尊重 postgreSQL 关键字而table
改为:tabl
package main
import (
"database/sql"
"fmt"
_ "github.com/lib/pq"
"github.com/lib/pq/hstore"
)
//ToNullString invalidates a sql.NullString if empty, validates if not empty
func ToNullString(s string) sql.NullString {
return sql.NullString{String: s, Valid: s != ""}
}
func main() {
var err error //To handle different errors
postgresConn, _ := sql.Open("postgres", os.Getenv("DB_CONN_URL"))
data := hstore.Hstore{}
data.Map = make(map[string]sql.NullString)
//Inserting the first element with:
//id: "024b54f2-a477-4715-984c-896bf0446dcf"
//my_field :"data => data"
id := "024b54f2-a477-4715-984c-896bf0446dcf"
data.Map["data"] = ToNullString("data")
_, err = postgresConn.Exec(`INSERT INTO tabl(id, my_field) VALUES ($2, $1)`, data, id)
if err != nil {
fmt.Println(err)
}
//Adding a second field in hstore:
//id: "024b54f2-a477-4715-984c-896bf0446dcf"
//my_field :"data => data", "data2 => more_data"
data.Map["data2"] = ToNullString("more_data")
_, err = postgresConn.Exec(`UPDATE tabl SET my_field = my_field || $1 WHERE id = $2`, data, id)
if err != nil {
fmt.Println(err)
}
//Modifying the first value field:
//id: "024b54f2-a477-4715-984c-896bf0446dcf"
//my_field :"data => value, data2 => more_data"
data.Map["data"] = ToNullString("value")
_, err = postgresConn.Exec(`UPDATE tabl SET my_field = my_field || $1 WHERE id = $2`, data, id)
if err != nil {
fmt.Println(err)
}
}
要获取更多信息以便hstore
从 sql 角度使用,您可以查看此处。
PD:不要table
用作表名,因为它是保留字。
PD2:我使用 postgresConn.Exec() 函数仅用于演示,如果您需要准备好的语句,请更改它,更多信息何时使用 Exec() 或 Query()此处。
PD3:使用映射时,尽量不要对键和值使用相同的值。