Postgresql 如何使用lib/pq将hstore对象插入postgres

Postgresql 如何使用lib/pq将hstore对象插入postgres,postgresql,go,hstore,pq,Postgresql,Go,Hstore,Pq,对于这张桌子 # \d table Table "public.table" Column | Type | Collation | Nullable | Default ------------+-----------------------------+-----------+----------+-------------------- id | uuid

对于这张桌子

# \d table
                            Table "public.table"
  Column   |            Type             | Collation | Nullable |      Default
------------+-----------------------------+-----------+----------+--------------------
id         | uuid                        |           | not null | uuid_generate_v4()
my_field   | hstore                      |           |          |
Indexes:
  "table_pkey" PRIMARY KEY, btree (id)
如何使用更新my_字段?我试着跟着

package "main"

import (
    "os"
    "database/sql"
  _ "github.com/lib/pq"
)

func main() {
  postgresConn, _ := sql.Open("postgres", os.Getenv("DB_CONN_URL"))
  id := "024b54f2-a477-4715-984c-896bf0446dcf"
  data := map[string]string{"data": "data"}
  postgresConn.QueryRow("UPDATE table SET my_field = $1 WHERE id = $2", data, id)
}
我不确定还可以使用哪种类型。

支持
hstore
,正如上面所说的,您可以找到相关信息。但它可能需要一些澄清或更好的例子

首先,此驱动程序中的存储是一个包含映射的结构:

type Hstore struct {
    Map map[string]sql.NullString
}
因此,如果要使用该映射,首先需要对其进行初始化:

h := hstore.Hstore{}
h.Map = make(map[string]sql.NullString)
然后,您可以使用它,但考虑到映射的形式为
[string]sql.NullString
,您需要将值字段转换为
sql.NullString
(一个可为null的字符串,golang中的默认字符串不可为null)。为此,您可以编写一个函数来完成该任务:

//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中的映射,这意味着如果您只更改值部分,它将更新值;但是如果您更改密钥和值,它将在您的hstore中添加一对新的(密钥,值),而不是替换旧的

为了澄清一点,我放了一个示例代码来测试它是如何工作的,这段代码应该与您的参数一起工作,为了尊重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)
    }
}
要从sql的角度获取更多信息以使用
hstore
,您可以查看

PD:不要使用
作为表名,因为它是一个表名

PD2:我使用postgresConn.Exec()函数只是为了演示,如果需要准备语句,请更改它,以及何时使用Exec()或Query()的详细信息


PD3:在使用映射时,尽量不要对键和值使用相同的值。

您尝试过吗?是的,我确实看过,但如何将字符串映射键入到它?您没有,因为Go中没有类型转换。您必须编写一个函数,根据映射值创建
hstore.hstore
值。或者,您可以声明一个更适合您需要的自定义类型,然后从
hstore
包中重新实现
Scan
Value
方法。