Postgres INSERT ON CONFLICT с JSONB

Я пытаюсь использовать Postgres в качестве хранилища документов, и у меня возникает проблема, когда я пытаюсь эффективно обновить документ, в котором синтаксическому анализатору Postgres не нравится оператор JSONB.

У меня есть таблица:

CREATE TABLE tbl (data jsonb NOT NULL);
CREATE UNIQUE INDEX ON tbl ((data->>'a'));

и я пытаюсь вставить данные с помощью:

INSERT INTO tbl (data) VALUES ('{ "a": "b" }'::jsonb) 
  ON CONFLICT (data->>a) 
  DO UPDATE SET data = data || '{ "a": "b" }'::jsonb

Я получаю это сообщение об ошибке:

ERROR:  syntax error at or near "->>"

Я пробовал данные - >> а, данные - >> 'а', данные-> а и, возможно, данные -> 'а'. Все это

Я хотел бы оставить столбец идентификатора (в примере a) в JSON, а не делать его столбцом в таблице.

Поддерживается ли то, что я пытаюсь сделать в настоящее время?


person Randy Layman    schedule 16.08.2016    source источник


Ответы (2)


У вас есть две проблемы:

1) Вам нужно добавить дополнительные скобки, например:

ON CONFLICT ((data->>'a'))

2) Перед последней data ссылкой нужно указать псевдоним таблицы, например:

DO UPDATE SET data = tbl.data || '{ "a": "b" }'::jsonb
person Nick    schedule 16.08.2016
comment
Похоже, это не работает. После добавления индекса я получаю ОШИБКУ: столбец tbl_data_a_uidx не существует - person Randy Layman; 16.08.2016
comment
Я использую PG 10.3, и мне кажется, что для этого нужно указать поле jsonb: ON CONFLICT ((data->>'a')) - person cjauvin; 23.03.2018
comment
@cjauvin - Вы правы - спасибо, что уловили. Я обновил ответ соответственно. - person Nick; 28.03.2018
comment
Я сделал именно то, что вы написали, и получил сообщение об ошибке, в котором говорится: нет уникального ограничения или ограничения исключения, соответствующего спецификации ON CONFLICT. - person Karam Haj; 26.09.2019
comment
@KaramHaj - Сообщение об ошибке довольно ясное. У вас нет ограничения, созданного для таблицы, которое соответствует спецификации / выражению в ON CONFLICT. Вам нужно его создать. - person Nick; 26.09.2019

Прочтите по этой теме эту документацию PostgreSQL. Вы можете использовать функцию json_populate_record для заполнения таблицы, если вы пытаетесь создать парсер json. Также см. Соответствующий вопрос: Как выполнять операции обновления столбцов типа JSONB в Postgres 9.4

person Aaron Morefield    schedule 16.08.2016