There's a table
CREATE TABLE IF NOT EXISTS table00 (
userid int8 PRIMARY KEY,
save date NOT NULL,
value int4
);
where I want to upsert values IFF the date
is not the same for a given userid
, which I'm doing like so:
INSERT INTO table00 (userid,save,value) VALUES (%s,%s,%s)
ON CONFLICT (userid) DO UPDATE SET save=EXCLUDED.save, value=EXCLUDED.value
WHERE table00.save!=EXCLUDED.save;
But I'd prefer to add
CREATE UNIQUE INDEX ON table00 (userid, save);
and drop the WHERE
clause. Is that possible?
But this isn't working, since values are still being updated even if they're on the same day; ie. the ON CONFLICT
seems to swallow up all errors and do the upsert anyways regardless of any uniqueness constraints.
The logic I want is: "If the userid
doesn't exist, then insert a new row. If the userid
exists, then update its row, unless the date is the same, in which case fail."
So, something like:
INSERT INTO table00 (userid,save,followers) VALUES (%s,%s,%s)
ON CONFLICT (userid) DO UPDATE SET save=EXCLUDED.save, followers=EXCLUDED.followers
ON CONFLICT (userid,date) ERROR;
userid
is the PK, your desired unique index on(userid, save)
does nothing useful (unless you want to point a multicolumn FK constraint to it). Also, updating a row never conflicts with itself, a unique index is the wrong tool. TheWHERE
clause you have is the right tool. Why would you want to break it?(userid, save)
is because I want to disable updates that happen on the samedate
(ie. any given row must be updated at most once per day). Let me know if it still doesn't make sense to have the unique index, because your observation is spot on. The only reason I want to do this is because I'm handling this situation in different table (with slightly different logic) with a unique index on(userid, save)
, and I'd like to handle the 2 tables in the same manner, for consistency.WHERE
solution doesn't throw an error on conflicts (which is not the fault ofWHERE
, but ofON CONFLICT
, I think), and the result is that I need different logic to handle each of the 2 tables, making my code uglier... (I'm using Postgres from Python withpsycopg2
)on conflict do nothing