Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Postgres UPSERT - don't update if all data the same?

I am using Postgres 9.6. I want to update a record if anything about it is different, but keep it the same if not.

This is my SQL, slightly simplified because my table actually has many more fields (run via psycopg2):

query = "INSERT INTO cap(scheme, year, code) "
query += "VALUES(%s, %s, %s) "
query += "ON CONFLICT DO NOTHING"
cursor.execute(query, ('abc', 2015, 'twu'))

However, if I run it twice with exactly the same values, I get two records in the database.

How can I amend this query so that providing the exact same values does not create a new record?

I've tried to read the ON CONFLICT UPDATE documentation but don't know how to adapt it for my case. In particular, it looks to me like DO NOTHING should not insert a row (the docs say: "ON CONFLICT DO NOTHING simply avoids inserting a row as its alternative action"), but it does insert a new row.

like image 999
Richard Avatar asked Oct 27 '25 09:10

Richard


1 Answers

INSERT ... ON CONFLICT ... needs a unique constraint to catch a conflict, e.g.

create table cap(
    scheme text, 
    year int, 
    code text, 
    unique(scheme, year, code) -- ! added
);

With the unique constraint multiple execution of this query

INSERT INTO cap(scheme, year, code)
VALUES('abc', 2015, 'twu')
ON CONFLICT DO NOTHING

will insert the row only once.

like image 151
klin Avatar answered Oct 28 '25 23:10

klin



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!