#database #postgresql #rules #insert-update
#База данных #postgresql #Правила #вставить-обновить
Вопрос:
Когда я создаю ПРАВИЛО обновления рядом с предложением CONFLICT, возникает эта ошибка.
Вот мой код конфликта
insert_query = "INSERT INTO my_company (id, name, login, logout) VALUES %s
ON CONFLICT (id) DO NOTHING"
мое ПРАВИЛО обновления
CREATE RULE log_shoelace AS ON UPDATE TO my_company
WHERE NEW.login <> OLD.login or NEW.logout <> OLD.logout
DO INSERT INTO my_company VALUES (
new.id, new.name, new.login, new.logout, new.interval_time, current_date);
поле таблицы my_company содержит идентификатор, имя, логин. выход из системы, interval_time, сегодня.
если какие-либо данные обновлены, вставьте эти данные в ту же таблицу. Но здесь я не могу использовать CONFLICT и RULE одновременно. Итак, что я могу сделать в этом случае?
Спасибо.
Создание таблицы и последовательности для тестирования:
CREATE SEQUENCE IF NOT EXISTS my_company_id_seq;
CREATE TABLE public.my_company
( id integer NOT NULL DEFAULT nextval('my_company_id_seq'::regclass)
, name character varying(50)
, login time without time zone
, logout time without time zone
, interval_time time without time zone
, today date DEFAULT CURRENT_DATE
, CONSTRAINT my_company_pkey PRIMARY KEY (id)
);
Комментарии:
1. Вы хотите вставить при конфликте или обновить при конфликте? Похоже, вы пытаетесь сделать
INSERT ... ON CONFLICT DO UPDATE
. Мне кажется, что вам вообще не нужно правило. Какие типы данных дляlogin
иlogout
? Если они естьtimestamp
, маловероятно, что они когда-либо будут равны.2. вход и выход из системы относятся к типу данных TIME
3. мой конфликт связан с insert, а правило — с update
4. но без создания ПРАВИЛА, как я могу вставить данные в поля today, когда что-то будет обновлено?
5. Взгляните на этот SQLFiddle и дайте мне знать, если вы все еще считаете, что вам нужно
RULE
: sqlfiddle.com /#!17/073e9/16 . Если я чего-то не упустил, вы получите те же результаты, используяINSERT ... ON CONFLICT UPDATE
. За исключением случаев, когда вашRULE
сбой произойдет из-за нарушения дубликата ключа.
Ответ №1:
ON CONFLICT
Директива должна содержаться в теле вашего правила:
CREATE RULE log_shoelace AS
ON UPDATE TO my_company
WHERE NEW.login <> OLD.login or NEW.logout <> OLD.logout
DO
INSERT INTO my_company VALUES (
new.id, new.name, new.login, new.logout, new.interval_time, current_date)
ON CONFLICT (id) DO NOTHING
Хорошо сказать, ON CONFLICT
директивы работают только тогда, когда целевая таблица имеет некоторое ограничение для отсрочки конфликта. В противном случае у вас будут ошибки во время выполнения, такие как:
No unique or exclusion constraint matching the ON CONFLICT specification.