Postgres upsert избежать 2-го уникального ограничения? - PullRequest
0 голосов
/ 05 ноября 2019

У меня есть таблица вида (на основе):

create table foo (
  name text unique,
  ref_id int,
  mod_time timestamptz
);

Я хотел бы иметь возможность вставить в нее, но вместо этого обновить mod_time, если (name, ref_id)) использовалась пара, и не удалось, если name использовался для другого ref_id.

. Я могу сделать это, создав другое уникальное ограничение следующим образом:

alter table foo add unique (name, ref_id);

Тогда

insert into foo values ( $1, $2, $3 )
on conflict (name, ref_id) do update set
  mod_time = excluded.mod_time;

будет работать так, как я хочу:

  • Если новое имя, вставляется
  • Если то же имя и ref_id, изменяет mod_time
  • Если то же самоеимя для другого ref_id, сбои

Однако стоимость является вторым уникальным индексом, который фактически является излишним для применения ограничения, поскольку записи, уникальные для name, автоматически будут уникальными для name иref_id. Есть ли обходной путь, который получит мне такое поведение без 2-го индекса и без дополнительных обращений к базе данных?

1 Ответ

1 голос
/ 05 ноября 2019

Это зависит от того, что вы подразумеваете под неудачей. Если это нормально, просто ничего не делать в этом случае: where If same name for different ref_id вы можете сделать следующее:

insert into foo values ($1, $2, $3)
on conflict (name) DO update set
mod_time = excluded.mod_time
WHERE foo.ref_id = excluded.ref_id;

Вы можете проверить, сколько строк было изменено после выполнения запроса, и вызвать исключение, если ни одна из них не была изменена. .

...