Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Postgres UPSERT on any constraint

In MySQL we can do the following on any constraint violation

INSERT INTO table {setters} ON DUPLICATE KEY UPDATE {setters}

Is there anyway to do this in Postgres ?

INSERT INTO table {setters} ON CONFLICT(*) DO UPDATE {setters}

Note: * = Any Possible Key

Why is this an important feature?

  • I want to make this code generic across multiple tables. So, I can't specify the keys as per current Postgres 9.5 syntax (Someone might argue, I could possibly store the keys on all tables and change the keys dynamically. First of all its not elegant and there is the following problem)
  • While the application is live, some new unique constraints could be added at run time. So, you can't specify this in your code at Compile time
  • Another Alternative is: In your app, you first try to insert and when there is a Duplicate key error, you catch catch it and try to do an update. This is really bad, as this is
    1. Not an atomic operation
    2. The latency between app server and the DB server doubles.
    3. Bulk insert is not possible
like image 239
Rahul Avatar asked Mar 04 '16 01:03

Rahul


People also ask

Does Postgres support upsert?

PostgreSQL lets you either add or modify a record within a table depending on whether the record already exists. This is commonly known as an "upsert" operation (a portmanteau of "insert" and "update").

How does upsert work in PostgreSQL?

In relational databases, the term upsert is referred to as merge. The idea is that when you insert a new row into the table, PostgreSQL will update the row if it already exists, otherwise, it will insert the new row. That is why we call the action is upsert (the combination of update or insert).

What is excluded in upsert?

EXCLUDED is the name the DBMS gives to a special table where we have all the rows proposed for INSERTION present. These rows may be inserted to this table as soon as the INSERT operation runs. This is mostly preceded by the ON CONFLICT DO UPDATE clause, specifically targeting this table.

Does Postgres do conflict?

ON CONFLICT DO NOTHING simply avoids inserting a row as its alternative action. ON CONFLICT DO UPDATE updates the existing row that conflicts with the row proposed for insertion as its alternative action. conflict_target can perform unique index inference.


1 Answers

Sure. PostgreSQL 9.5+ allows you to do this, in this manner:

The MySQL query:

INSERT INTO tablename (a,b,c) VALUES (1,2,3)
  ON DUPLICATE KEY UPDATE c=c+1;

In PostgreSQL becomes:

INSERT INTO tablename (a, b, c) values (1, 2, 10)
ON CONFLICT (a) DO UPDATE SET c = tablename.c + 1;
like image 165
Robins Tharakan Avatar answered Nov 15 '22 04:11

Robins Tharakan