Reputation: 65530
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.
Upvotes: 4
Views: 1191
Reputation: 121594
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.
Upvotes: 6