Replies: 3 comments
-
It's invalid to call DB[:authors].
insert_conflict(target: :id, update: {name: Sequel[:excluded][:name]}).
multi_insert([{id: 1, name: 'Jane Roe'}, {id: Sequel.function(:nextval, 'authors_id_seq'), name: 'Bob Dole'}]) |
Beta Was this translation helpful? Give feedback.
-
Thank you for the ridiculously fast response! 💨 I think my gears were slowly grinding in that direction. 🤓 Now I have to decide if I want to code Postgres sequence names into my app, or split the operation into two queries (what I implemented so far). Thank you! 💚 |
Beta Was this translation helpful? Give feedback.
-
I wanted to circle back for future readers with another solution to this problem. In most instances where your This is likely easier, since you don't need to reference the name of a Postgres sequence in your code. This is working for me: DB[:authors].
insert_conflict(target: :id, update: {name: Sequel[:excluded][:name]}).
multi_insert([{id: 1, name: 'Jane Roe'}, {id: Sequel.lit('DEFAULT'), name: 'Bob Dole'}]) |
Beta Was this translation helpful? Give feedback.
-
Can I use
insert_conflict
andmulti_insert
to add new rows and update existing rows at once?It seems to me that the requirement that all hashes passed to
multi_insert
have the same keys is preventing this use case, since updated rows have anid
and new rows don't.Assumptions
authors
.id
andname
.id
is the primary key.insert_conflict
optionsmulti_insert
scenarios and resultsIf I create an Array of Hashes like so:
And chain the following to the above
insert_conflict
method :It will work and create two records.
If I do the same with the following values:
The first record will be updated accordingly.
However, if I try the same method with the following values:
It will fail with a
NotNullViolation
, stating that "null value in column 'id' violates not-null constraint," when processing the second Hash.Solution?
Is there a simple solution for this use case?
Based on my research, I could filter the new records and add an
:id
key that invokes a Postgres function to retrieve the nextid
in the table's primary key sequence to set its value. In this way, all hashes would have an:id
key. But this feels really clunky and I'm not sure if it would cause problems down the road. I haven't tried this, but the SQL could look something like this, I think:Even if this works, I haven't thought through how to do this in Sequel yet.
It occurs to me that this whole issue may be a constraint of SQL itself. If so, the only other strategy I can think of is to partition the
values
Array into new row hashes and updated row hashes and operate on them separately. I believe I can do this with the very sameinsert_conflict
method, as long as I pass the two groups separately. But I am curious if there is a way to do it all in one go.Thank you!
Thank you kindly for reading this, and for any advice you can offer! 🤓
Beta Was this translation helpful? Give feedback.
All reactions