Postgresql Исключение с мягко удаленными строками
Я пытаюсь выполнить ограничение PostgreSQL на следующую таблицу:
CREATE TABLE contracts
(
id bigint NOT NULL,
startdate date NOT NULL,
enddate date NOT NULL,
price numeric(19,2) NOT NULL,
deleted boolean NOT NULL,
supplier_id bigint NOT NULL,
)
Содержит контракты для поставщиков с разными ценами. Для данного времени может существовать только один контракт для данного поставщика. Я сделал следующее ограничение для обеспечения этого:
ALTER TABLE contracts ADD CONSTRAINT overlaping_contracts EXCLUDE USING GIST (
supplier_id WITH =,
daterange(startdate, enddate) WITH &&
);
Это гарантирует, что нельзя вставить новый контракт, который перекрывается с уже существующим контрактом. Теперь мы также поддерживаем "мягкое удаление" контрактов. Это делает недействительным старый контракт и устанавливает флаг "удаленный" в true. Теперь я хочу вставить новый контракт на тот же период, но это накладывается, вызывая ограничение.
Я попытался объединить условный индекс unqiue с приведенным выше соглашением, но не могу заставить его работать. Документация по исключающим ограничениям довольно мала.
Мой инстинкт подсказывает мне, что я должен добавить что-то вроде
deleted = false
к ограничению исключения, но я не могу найти правильный синтаксис для этого.
Как я могу объединить ограничение исключения с условным уникальным индексом, чтобы я мог применять перекрывающее ограничение только для строк, которые удалили = false?
1 ответ
Это должно сделать трюк:
ALTER TABLE contracts ADD CONSTRAINT overlapping_contracts EXCLUDE USING GIST (
supplier_id WITH =,
daterange(startdate, enddate) WITH &&
) WHERE (NOT deleted);
Используя эту суть https://gist.github.com/fphilipe/0a2a3d50a9f3834683bf