Upsert many нарушает уникальное ограничение в Postgres

Я пытаюсь обновить записи контактов в Postgres на основе частичного уникального индекса (называемого contacts_unique_idx) в столбце jsonb data, логическом столбце deleted и логическом столбце duplicated:

CREATE UNIQUE INDEX contacts_uniqueness_idx  ON contacts(
(data->>'customerId'),
LOWER(COALESCE(data->'data'->'profile'->'location'->>'formatted', '')), LOWER(COALESCE(data->'data'->'profile'->'name'->'anglican'->>'given', '')),
LOWER(COALESCE(data->'data'->'profile'->'name'->'anglican'->>'middlename', '')),
LOWER(COALESCE(data->'data'->'profile'->'name'->'anglican'->>'surname', '')),
LOWER(COALESCE(data->'data'->'profile'->'name'->'anglican'->>'suffix', '')), LOWER(COALESCE(data->'data'->'profile'->'name'->'anglican'->>'title', ''))
)
    WHERE deleted = false and duplicated = false

Моя функция upsert (ниже, с удаленным values для краткости) успешно вставляет одну запись контакта и несколько записей контактов, если они еще не существуют. Он также успешно обновляет существующую запись, если я передаю одно значение для обновления, строит новый объект jsonb в столбце data на основе существующих данных записи и обновляет данные записи в соответствии с частью функции DO UPDATE.

Однако при передаче более одного значения в upsert я получаю сообщение об ошибке: ERROR: duplicate key value violates unique constraint "contacts_unique_idx", уникальное ограничение, на котором должно произойти обновление.

INSERT INTO contacts (id, data)
VALUES ({uuid} :: {dataObject} jsonb)
ON CONFLICT (
(data->>'customerId'),
LOWER(COALESCE(data->'data'->'profile'->'location'->>'formatted', '')),
LOWER(COALESCE(data->'data'->'profile'->'name'->'anglican'->>'given', '')),
LOWER(COALESCE(data->'data'->'profile'->'name'->'anglican'->>'middlename', '')),
LOWER(COALESCE(data->'data'->'profile'->'name'->'anglican'->>'surname', '')),
LOWER(COALESCE(data->'data'->'profile'->'name'->'anglican'->>'suffix', '')),
LOWER(COALESCE(data->'data'->'profile'->'name'->'anglican'->>'title', ''))
      )
      WHERE deleted = false and duplicated = false
      DO UPDATE
      SET data =
      jsonb_build_object(
        'id', contacts.id,
        'data', jsonb_build_object(
          'fields',(contacts.data->'data'->>'fields')::jsonb || (excluded.data->'data'->>'fields')::jsonb,
          'profile',(excluded.data->'data'->>'profile')::jsonb,
          'status',contacts.data->'data'->>'status',
          'contacted',contacts.data->'data'->>'contacted',
          'successful',contacts.data->'data'->>'successful',
          'reservation',(contacts.data->'data'->>'reservation')::jsonb
        ),
        'meta', jsonb_build_object(
          'etag',contacts.data->'meta'->>'etag',
          'created',contacts.data->'meta'->>'created',
          'modified',excluded.data->'meta'->>'modified',
          'resource',contacts.data->'meta'->>'resource',
          'createdBy',contacts.data->'meta'->>'createdBy',
          'isDeleted',contacts.data-> 'meta'->>'isDeleted',
          'modifiedBy',excluded.data->'meta'->>'modifiedBy'
        ),
        'customerId',contacts.data->>'customerId',
        'securityGroupId',contacts.data->>'securityGroupId'
      )
      RETURNING *;

Это проблема параллелизма? Почему я могу загрузить одну запись, а не несколько?

Я точно не проверял, но может ли UPDATE нарушить ограничение?

Laurenz Albe 11.10.2018 17:30

Для всех, кому интересно, использование вложенного jsonb_set для обновления data и meta вместо использования jsonb_build_object решило проблему.

manj 11.10.2018 17:38
ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
0
2
217
0

Другие вопросы по теме