Golang PGX как добавлять значения в jsonb?

При вставке ключа и значения получаю ошибку could not determine data type of parameter $1
Запрос
query := `
    UPDATE type
    SET characteristics = jsonb_insert(
        characteristics, '{$1}', '{"type": "$2", "measure": "$3"}'::jsonb
    )
    WHERE id=$4`

	tag, err := conn.Exec(ctx, query,
		c.Name,      // string
		c.Type,      // string
		c.Measure,   // string
		c.ID,        // uint64
	)


Пробовал явно указывать тип $1
query := `
    UPDATE type
    SET characteristics = jsonb_insert(
        characteristics, '{$1}'::text, '{"type": "$2", "measure": "$3"}'::jsonb
    )
    WHERE id=$4`

Так тоже ошибка : function jsonb_insert(jsonb, text, jsonb) does not exist

Можно конечно сделать так

query := fmt.Sprintf(`
    UPDATE type
    SET characteristics = jsonb_insert(
        characteristics, '{%s}', '{"type": "%s", "measure": "%s"}'::jsonb
    )
    WHERE id=%d`,
		c.Name,
		c.Type,
		c.Measure,
		c.ID)

	tag, err := conn.Exec(ctx, query)

но хотелось бы с помощью pgx


Postgres v13
PGX v5
  • Вопрос задан
  • 1128 просмотров
Решения вопроса 1
@Wirusnyy-chel
Когда вы указываете
'{$1}'
постгрес воспринимает это как просто строку, а не как параметр для вставки.


Пробовал явно указывать тип $1
query := `
UPDATE type
SET characteristics = jsonb_insert(
characteristics, '{$1}'::text, '{"type": "$2", "measure": "$3"}'::jsonb
)
WHERE id=$4`

Так тоже ошибка : function jsonb_insert(jsonb, text, jsonb) does not exist

У функции jsonb_insert сигнатура
jsonb_insert(target jsonb, path text[], new_value jsonb [, insert_after boolean])
Поэтому строка `'{$1}'::text'`, должна быть `'{$1}'::text[]'`. (Но и это не совсем поможет)

Можно преобразовать это следующим образом:
query := `
    UPDATE type
    SET characteristics = jsonb_insert(
        characteristics, array[$1::text], 
       jsonb_build_object('type', $2, 'measure', '$3')
    )
    WHERE id=$4`

  tag, err := conn.Exec(ctx, query,
    c.Name,      // string
    c.Type,      // string
    c.Measure,   // string
    c.ID,        // uint64
  )


Или позволить pxg самому собрать jsonb:

query := `
    UPDATE type
    SET characteristics = jsonb_insert(
        characteristics, array[$1::text], $2
    )
    WHERE id=$3`

  tag, err := conn.Exec(ctx, query,
    c.Name,      // string
   struct{ // лучше вынести как отдельный тип
     Type string `json:"type"`
     Measure string `json:"measure"`
    }{c.Type, c.Measure}
    c.ID,        // uint64
  )
Ответ написан
Пригласить эксперта
Ответы на вопрос 2
Melkij
@Melkij
PostgreSQL DBA
сильно сомневаюсь, что $2 и $3 тоже у вас корректно указаны с точки зрения библиотеки и их хоть кто-то будет искать внутри текстового литерала, так что так:
UPDATE type
    SET characteristics = jsonb_insert(
        characteristics, array[$1], jsonb_build_object('type', $2, 'measure', $3)
    )
    WHERE id=$4

или
update type set characteristics[$1] = jsonb_build_object('type', $2, 'measure', $3) WHERE id=$4;
Ответ написан
uvelichitel
@uvelichitel Куратор тега Go
habrahabr.ru/users/uvelichitel
А попробуйте []string
query := `
    UPDATE type
    SET characteristics = jsonb_insert(
        characteristics, '{$1}', '{"type": "$2", "measure": "$3"}'::jsonb
    )
    WHERE id=$4`

  tag, err := conn.Exec(ctx, query,
    []string{c.Name},      // Вот здесь попробуйте []string
    c.Type,      // string
    c.Measure,   // string
    c.ID,        // uint64
  )
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы