Search code examples
databasepostgresqlrulesinsert-update

psycopg2.NotSupportedError: INSERT with ON CONFLICT clause cannot be used with table that has INSERT or UPDATE rules


When i'm creating a update RULE beside of CONFLICT clause then that error is throwing.

Here my conflict code

 insert_query = "INSERT INTO my_company (id, name, login, logout) VALUES %s\
                    ON CONFLICT (id) DO NOTHING"

my update RULE

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 table field contains id, name, login. logout, interval_time, today.

if any data is updated then insert those data into same table. But here i can't use CONFLICT and RULE in the same time. So in this case what can i do?

Thanks.

Table creation and sequence creation for testing:

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) 
);

Solution

  • The ON CONFLICT directive should go in your rule body:

    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
    

    Good to say, ON CONFLICT directives only work when the target table has some constraint to defer the conflict. Otherwise, you'll have runtime errors, like:

    No unique or exclusion constraint matching the ON CONFLICT specification.