PostgreSQL ON CONFLICT с уникальным именем ограничения из нескольких столбцов - PullRequest
0 голосов
/ 27 сентября 2018

Я сталкиваюсь с поведением, которое я не понимаю при попытке сделать UPSERT с PostgreSQL.Кажется, что документы указывают, что цель конфликта оператора INSERT может быть либо индексным выражением , либо именем ограничения.Однако при попытке обратиться к имени ограничения я получаю ошибку «столбец ... не существует».

Моя первая попытка состояла в том, чтобы просто создать индекс UNIQUE, который отлично работает с выводом ограничения:

create table kv (key text, value text, extra text);
create unique index kv_key_value on kv(key, value);
insert into kv (key, value) values ('k1', 'v1');
-- this works:
insert into kv (key, value, extra) values ('k1', 'v1', 'e1')
  on conflict (key, value) do update set extra=excluded.extra;

-- this does not
insert into kv (key, value, extra) values ('k1', 'v1', 'e1')
  on conflict (kv_key_value) do update set extra=excluded.extra;

Описывая приведенную выше таблицу, я вижу следующее в разделе «Индексы»:

"kv_key_value" UNIQUE, btree (key, value)

Моя вторая попытка заключалась в явном введении уникального ограничения в таблицу создания:

create table kv (
  key text,
  value text,
  extra text,
  constraint kv_key_value unique(key, value));

Описывая вышеприведенную таблицу, вывод «Indexes:» немного отличается («UNIQUE CONSTRAINT» против «UNIQUE» в предыдущем примере):

"kv_key_value" UNIQUE CONSTRAINT, btree (key, value)

Однако я все еще не могучтобы указать имя ограничения в качестве цели конфликта:

insert into kv (key, value, extra) values ('k1', 'v1', 'e1')
  on conflict (kv_key_value) do update set extra=excluded.extra;
ERROR:  column "kv_key_value" does not exist
LINE 2:       on conflict (kv_key_value) do update set extra=exclude...

Я что-то здесь неправильно понимаю?Я полностью понимаю, что могу использовать эквивалентное выражение и полагаться на вывод ограничения, но я хотел бы знать, почему имя ограничения не работает, когда документы заставляют его звучать так, как должно?

1 Ответ

0 голосов
/ 27 сентября 2018

Вы неправильно указали синтаксис.

Для ограничения это должно быть:

INSERT INTO kv (key, value, extra)
   VALUES ('k1', 'v1', 'e1')
   ON CONFLICT ON CONSTRAINT kv_key_value
      DO UPDATE SET extra = excluded.extra;
...