Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support INSERT ... ON CONFLICT DO NOTHING/UPDATE (also known as UPSERT) for PostgreSQL #187

Closed
JustusLauten opened this issue May 8, 2015 · 9 comments

Comments

@JustusLauten
Copy link

The feature exists already for MySQL databases and can be used with the :on_duplicate_key_update parameter. Upcoming versions of PostgreSQL will feature a similar functionality:

http://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=168d5805e4c08bed7b95d351bf097cff7c07dd65

It would be cool to see this feature in activerecord-import, also for PostgreSQL databases.

@zdennis
Copy link
Owner

zdennis commented May 18, 2015

@JustusLauten ooh, that will be nice for Postgres to get. Any idea what version they are planning on including this in?

@johnnaegle
Copy link
Contributor

Postgres 9.5: https://wiki.postgresql.org/wiki/UPSERT

@bkingon
Copy link

bkingon commented Sep 9, 2015

@zdennis any chance we could get this implemented?

@ptolts
Copy link

ptolts commented Nov 6, 2015

#209

^^ Quick and dirty. Maybe someone wants to take it on and make it merge worthy.

@jkowens
Copy link
Collaborator

jkowens commented Jan 8, 2016

Postgres 9.5 was released yesterday with the UPSERT feature. 👍

http://www.postgresql.org/about/news/1636/

@ptolts
Copy link

ptolts commented Jan 8, 2016

It's butter

@shlima
Copy link

shlima commented Jan 10, 2016

+1

@jkowens
Copy link
Collaborator

jkowens commented Jan 11, 2016

The implementation for UPSERT with Postgres is going to have to be slightly different than that for MySQL.

Postgres requires that the constraint that may result in a duplicate key error be specified, where MySQL does not. It can referenced by either column name(s):

INSERT INTO countries (country, updated_at) VALUES ('France', now()),('Japan', now()) ON CONFLICT (country) DO UPDATE SET countries.updated_at = EXCLUDED.updated_at;

Or by constraint name:

INSERT INTO countries (country, updated_at) VALUES ('France', now()),('Japan', now()) ON CONFLICT ON CONSTRAINT countries_pkey DO UPDATE SET countries.updated_at = EXCLUDED.updated_at;

The documentation indicates column name should be preferred (see the "Tip" for on conflict clause). That being said, I was thinking it would be acceptable to just make column names the requirement for identifying the unique constraint.

Any thoughts about what this more explicit syntax should look like? I was thinking that even though it doesn't match the Postgres syntax, it might be nice to stick with the :on_duplicate_key_update parameter. This would be a hash with an attribute for the key and one for the columns that should be updated.

Country.import [country], on_duplicate_key_update: { key: :country, columns: [:updated_at] }

:key would have to take either a single value or array of column names and :columns could be either an array or hash similar to the existing MySQL functionality.

Thoughts on the naming? Other suggestions?

@rwilliams
Copy link

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants