【问题标题】:How to insert a hstore object using lib/pq to postgres如何使用 lib/pq 将 hstore 对象插入到 postgres
【发布时间】:2019-03-05 08:07:13
【问题描述】:

对于这个表,

# \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)

如何使用lib/pq 更新 my_field?我试过了,

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)
}

我不确定可以使用哪种其他类型。

【问题讨论】:

  • 是的,我确实看过它,但如何将我的字符串映射类型转换为它?
  • 你不需要,因为 Go 中没有类型转换。您必须编写一个函数,从您的地图值创建一个hstore.Hstore 值。或者,您可以声明一个更适合您需求的自定义类型,然后重新实现 hstore 包中的 ScanValue 方法。

标签: postgresql go hstore pq


【解决方案1】:

lib/pq 支持hstore,正如mkopriva 所说,您可以找到信息here。但它可能需要一些澄清或更好的例子。

首先,这个驱动中的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) 而不是替换旧的。

为了澄清一点,我放了一个示例代码来测试它是如何工作的,这段代码应该与你的参数一起工作,我刚刚将 table 更改为 tabl 以尊重 postgreSQL 关键字:

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,您可以查看 here

PD:不要使用table 作为表名,因为它是reserved word

PD2:我使用 postgresConn.Exec() 函数仅用于演示,如果您需要准备好的语句,请更改它,更多信息何时使用 Exec() 或 Query() here

PD3:使用map时,尽量不要为key和value使用相同的值。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-12-16
    • 2020-04-14
    • 2021-12-22
    • 2021-12-27
    • 2022-12-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多