Как вставить объект hstore, используя lib / pq для postgres - PullRequest
0 голосов
/ 05 марта 2019

Для этой таблицы

# \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_field, используя lib / pq ?Я попробовал следующее,

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

Я не уверен, какой другой тип можно использовать.

1 Ответ

0 голосов
/ 08 марта 2019

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 (строка, допускающая значение 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 вместо того, чтобы заменить старые.

Чтобы пояснить это немного, я поместил пример кодачтобы проверить, как он работает, этот код должен работать с вашими параметрами, я просто изменил 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)
    }
}

Чтобы получить больше информации для работыс hstore с точки зрения sql, вы можете посмотреть здесь .

PD: Не используйте table в качестве имени таблицы, потому что это зарезервированное слово .

PD2: я использую функцию postgresConn.Exec () только для демонстрации, измените ее, если вам нужны подготовленные операторы, больше информации о том, когда использовать Exec () или Query () здесь .

PD3: при использовании карты старайтесь не использовать одно и то же значение для ключа и значения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...