Как добавить элемент в массив полей json в Postgres - PullRequest
1 голос
/ 29 марта 2019

Я пытаюсь добавить данные в массив, который принадлежит полю json в postgres. При использовании pgAdmin я знаю, что следующий запрос работает. ~

UPDATE lesson SET data =
    jsonb_set (data, '{pages, 999999}', '{"pageNum": 2, "pageType": "voc"}', True)
WHERE id = 2;

Я просто пытаюсь заставить работать вышеупомянутый запрос через мой API остальных, написанный на go. Я получаю сообщение об ошибке «pq: неверный синтаксис ввода для типа json».

мой код выглядит следующим образом ~

_, err := db.Exec(`
    UPDATE lessons SET data =
        jsonb_set (data, '{pages, 999999}','{"pageNum": $1, "pageType": $2}', True) 
    WHERE id = $3`,
    pageNum, pageType, id) // variable types are int string int

Я подозреваю, что драйвер postgres не интерполирует параметры $. Это сработает, если я использую fmt.Sprinf () для всего запроса, но я пытаюсь избежать атак с использованием SQL-инъекций и хотел бы воспользоваться встроенными мерами безопасности библиотеки go sql.

Для справки мои данные структурированы следующим образом ~ Таблица уроков

Lessons
   id    int
   data  jsonb

Структуры Го:

type Lesson struct {
    ID    int    `json:"id"`
    Name  string  `json:"name"`
    Pages []Page  `json:"pages"`
}

type Page struct {
    PageNum    int  `json:"pageNum"`
    PageType   string `json:"pageType"`

1 Ответ

3 голосов
/ 29 марта 2019

Вы не можете использовать параметры запроса в строке в Postgres. Либо передайте всю строку в Postgres как один параметр:

str := fmt.Sprintf('{"pageNum": %d, "pageType": %q}', pageNum, pageType)
_, err := db.Exec(`
    UPDATE lessons SET data =
        jsonb_set (data, '{pages, 999999}', $1, True) 
    WHERE id = $2`,
    str, id) // variable types are int string int

или используйте конкатенацию строк , чтобы сделать это на стороне сервера:

_, err := db.Exec(`
    UPDATE lessons SET data =
        jsonb_set (data, '{pages, 999999}','{"pageNum": ' || $1 || ', "pageType": ' || $2 || '}', True) 
    WHERE id = $3`,
    pageNum, pageType, id) // variable types are int string int

Лучший / самый безопасный, вероятно, первый подход, с полным маршалингом JSON в вашем клиенте, а не простым fmt.Sprintf. Я оставляю это как упражнение для читателя.

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