Я сталкиваюсь с поведением, которое я не понимаю при попытке сделать 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...
Я что-то здесь неправильно понимаю?Я полностью понимаю, что могу использовать эквивалентное выражение и полагаться на вывод ограничения, но я хотел бы знать, почему имя ограничения не работает, когда документы заставляют его звучать так, как должно?