-
-
Notifications
You must be signed in to change notification settings - Fork 4.3k
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
feat(postgres): enabling the updateOnDuplicate BulkCreate option #11163
Conversation
Codecov Report
@@ Coverage Diff @@
## master #11163 +/- ##
==========================================
+ Coverage 96.34% 96.34% +<.01%
==========================================
Files 94 94
Lines 9023 9029 +6
==========================================
+ Hits 8693 8699 +6
Misses 330 330
Continue to review full report at Codecov.
|
if (this._dialect.supports.inserts.updateOnDuplicate == ' ON CONFLICT DO UPDATE SET') { // postgres | ||
// If no conflict target columns were specified, use the primary key names from options.upsertKeys | ||
onDuplicateKeyUpdate = ` ON CONFLICT (${options.upsertKeys.map(attr => { | ||
return `"${attr}"`; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This one can be inlined eg. => `...`
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also use this.quoteIdentifier(<attr>)
instead of "<attr>"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In commit 8381105 I updated with quoteIdentifier()
(oops).
I am not sure how best to inline this though? Especially since I added the quoteIdentifier()
call? My JS-fu is weak, there is probably some classic syntax I am not familiar with. I was following the existing code example which looks like this:
onDuplicateKeyUpdate = `${this._dialect.supports.inserts.updateOnDuplicate} ${options.updateOnDuplicate.map(attr => {
const key = this.quoteIdentifier(attr);
return `${key}=VALUES(${key})`;
}).join(',')}`;
lib/dialects/mariadb/index.js
Outdated
@@ -28,7 +28,8 @@ MariadbDialect.prototype.supports = _.merge( | |||
schemas: true, | |||
inserts: { | |||
ignoreDuplicates: ' IGNORE', | |||
updateOnDuplicate: true | |||
updateOnDuplicate: ' ON DUPLICATE KEY UPDATE' | |||
//updateOnDuplicate: true // now using a string instead of boolean, like ignoreDuplicates |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be removed and written in the changelog.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I removed these in commit 8381105. Any guidance on how to update the changelog? Is there a manually generated changelog in the docs somewhere? Thanks
What's the next step? Do I just need to update the Documentation? Or is there anything else I should improve? Thanks |
lib/dialects/postgres/index.js
Outdated
onConflictDoNothing: ' ON CONFLICT DO NOTHING' | ||
onConflictDoNothing: ' ON CONFLICT DO NOTHING', | ||
updateOnDuplicate: ' ON CONFLICT DO UPDATE SET' | ||
// updateOnDuplicate: true // this is why mysql does |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove this
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed the comment
@thaddeusmt Hello! Thanks for the PR! Please update the docs: here and here. |
the same refactor on the upsert method and it will be a major improvement for postgres insert performance in sequelize, nice work! |
I missed those ESDoc comments, thanks. I updated them to add that Postgres 9.5 is supported. |
I have thought about replacing the Postgres |
@thaddeusmt Hi, thanks for the changes. I have one more request. I am bothered by the specific, explicit mention of Postgres 9.5. This makes it seem that no other version whatsoever is supported. Is this true? Is there a version of Postgres that is not supported? |
|
@sushantdhiman Ah, so by 9.5 it is meant "9.5 and above"? I think that deserves clarification |
Docs updated |
🎉 This PR is included in version 5.11.0 🎉 The release is available on: Your semantic-release bot 📦🚀 |
Been trying to use this but keep getting an error |
@prachikhadke You should open a new issue with a SSCCE/MCVE/reprex so we can help you 👍 |
@prachikhadke Link me to (or tag me in) an Issue with some details for reproducing and I'll take a look. I'm curious:
Thanks |
Where |
@prachikhadke The first thing that jumps out is that you are not setting It might still be useful to see how the model is created. Is the primary key |
@thaddeusmt I did try setting the |
@prachikhadke Please open a new bug report for this, instead of discussing here. |
Pull Request check-list
Please make sure to review and check all of these items:
npm run test
ornpm run test-DIALECT
pass with this change (including linting)?Description of change
I have attempted to enable the
BulkCreate()
updateOnDuplicate
option for the Postgres dialect using theINSERT ... ON CONFLICT DO NOTHING/UPDATE
syntax added in Postgres 9.5. This essentially enables "upsert" functionality on "BulkCreate" operations (as is currently provided for the MySql and Mariadb dialects with theON DUPLICATE KEY UPDATE
functionality).NOTE: The Postgres
upsert()
functionality still uses theINSERT EXCEPTION WHEN
method, I did not refactor that to useON CONFLICT
.The Postgres
ON CONFLICT
command requires either listing out the columns to key conflicts on, or using an actual unique constraint by name. This easiest way I could see to support both primary key and "unique" constraints in the model definitions was to add some logic in thebulkInsertQuery()
method that looks up those columns, and then add to theON CONFLICT
command directly. By default it uses the primary key columns, but if there is a separate unique constraint in the model definition it will use that instead.I added an integration test called
should support the updateOnDuplicate option with primary keys
to test the primary key case, since the existingshould support the updateOnDuplicate option
test only checked unique constraints. The unit and integration tests are passing for Postgres.I am only set up to run the tests with the Postgres dialect right now, so hopefully I didn't break any other dialects...
I think this might fix issues #4132 and #6325 and #3354 and #4324.
It appears this outstanding PR #6325 was attempting to do this as well.
This is my first attempt at a PR on a project like this, please advise on how I can improve my submission, thank you.