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

feat(postgres): Add upsertIndex and upsertKeys options to BulkCreateOptions #11611

Closed

Conversation

fnimick
Copy link

@fnimick fnimick commented Oct 25, 2019

This allows the use of a unique index for a bulkCreate with
updateOnDuplicate set, in postgres. The unique index may be
a partial index.

Pull Request check-list

Please make sure to review and check all of these items:

  • Does npm run test or npm run test-DIALECT pass with this change (including linting)?
  • Does the description below contain a link to an existing issue (Closes #[issue]) or a description of the issue you are solving?
  • Have you added new tests to prevent regressions?
  • Is a documentation update included (if this change modifies existing APIs, or introduces new ones)?
  • Did you update the typescript typings accordingly (if applicable)?
  • Did you follow the commit message conventions explained in CONTRIBUTING.md?

Description of change

This change adds the ability to specify upsertIndex or upsertKeys in BulkCreateOptions, so that a ON CONFLICT clause can be generated using columns other than the table's primary key.

Note: I was not able to get the tests running on my machine, and would appreciate help writing a new test for this functionality.

Closes #11534, #11569

@fnimick fnimick force-pushed the unique-index-updateOnDuplicate branch from 13287e0 to ce8261b Compare October 25, 2019 15:03
@codecov
Copy link

codecov bot commented Oct 25, 2019

Codecov Report

Merging #11611 into master will increase coverage by 0.47%.
The diff coverage is 100.00%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master   #11611      +/-   ##
==========================================
+ Coverage   95.92%   96.40%   +0.47%     
==========================================
  Files          92       95       +3     
  Lines        8912     9128     +216     
==========================================
+ Hits         8549     8800     +251     
+ Misses        363      328      -35     
Impacted Files Coverage Δ
lib/dialects/abstract/query-generator.js 97.40% <100.00%> (+<0.01%) ⬆️
lib/model.js 96.64% <100.00%> (+0.01%) ⬆️
lib/dialects/mariadb/index.js 100.00% <0.00%> (ø)
lib/dialects/mariadb/query.js 87.96% <0.00%> (ø)
lib/dialects/mariadb/connection-manager.js 100.00% <0.00%> (ø)
lib/sequelize.js 95.81% <0.00%> (+0.64%) ⬆️
lib/dialects/abstract/query-interface.js 93.76% <0.00%> (+1.86%) ⬆️
lib/dialects/mariadb/data-types.js 100.00% <0.00%> (+52.63%) ⬆️
lib/dialects/mariadb/query-generator.js 100.00% <0.00%> (+81.25%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 95f7fb5...42f64bf. Read the comment docs.

@fnimick
Copy link
Author

fnimick commented Oct 25, 2019

Note: if anyone wants to use this while we go through the PR process, I have a patch-package patch available here: https://gist.github.com/fnimick/5dd3c6855cea6e000c86d1bc38876958

EDIT as of 6/9/2020: I have a new patch for sequelize 5.21.12 to support this in postgres and sqlite: https://gist.github.com/fnimick/313091df3ecc6c5e5f17be1e0950c33f

@papb
Copy link
Member

papb commented Oct 26, 2019

Hello! I see you are a first-time contributor, thank you for taking the time to help Sequelize! I hope to see more PRs from you in the future!

To help you write tests, can you please first show usage examples of your feature?

@papb papb added type: feature For issues and PRs. For new features. Never breaking changes. status: awaiting response For issues and PRs. OP must respond (or change something, if it is a PR). Maintainers have no action labels Oct 26, 2019
@fnimick
Copy link
Author

fnimick commented Oct 28, 2019

A usage example for upsertIndex:

model.bulkCreate(data, {
  updateOnDuplicate: ['updateField'],
  upsertIndex: 'unique_index',
});

NOTE: the index in question here must be defined on the model as well.

A usage example for upsertKeys with a partial index:

model.bulkCreate(data, {
  updateOnDuplicate: ['updateField'],
  upsertKeys: {
    fields: ['unique_field_one', 'unique_field_two'],
    where: { deleted_at: { [Op.is]: null } },
  },
});

A usage example for upsertKeys:

model.bulkCreate(data, {
  updateOnDuplicate: ['updateField'],
  upsertKeys: ['unique_field_one', 'unique_field_two'],
});

@papb papb added status: awaiting maintainer and removed status: awaiting response For issues and PRs. OP must respond (or change something, if it is a PR). Maintainers have no action labels Nov 2, 2019
@fnimick fnimick force-pushed the unique-index-updateOnDuplicate branch from ce8261b to c66afd6 Compare January 8, 2020 19:27
@fnimick
Copy link
Author

fnimick commented Jan 8, 2020

@papb just updated this to resolve conflicts with #11666 . Still not sure how to write tests but can investigate if necessary.

@papb
Copy link
Member

papb commented Jan 14, 2020

Hello 😬 thank you very much!!

@papb
Copy link
Member

papb commented Jan 15, 2020

If you are having trouble to write tests, I suggest you try playing around with sequelize-sscce, if you can make short pieces of code that verify what you want, converting them to real tests will be almost trivial :) Let me know!

@molinajulian
Copy link

Hi everyone! 👋 Good job in this PR 🎉.
I recently have a problem with bulkInsert because of this bug
I think that it's a breaking change for version 5.x, it would be nice if we don't change the interface and we use the unique keys in the model for know if exist a composite unique keys or keep this change for versión 6.x and release a fix in another PR for 5.x.
@fnimick if you need help for tests, you can tell me

@fnimick
Copy link
Author

fnimick commented Mar 16, 2020

Closed because a better approach has been merged in - see #11984

@fnimick fnimick closed this Mar 16, 2020
@fnimick
Copy link
Author

fnimick commented Jun 8, 2020

@thaddeusmt went to implement my use case for this PR with your updated updateOnDuplicate and realized there's a case that my branch handles, but yours (I don't think) does - a partial unique index. In our case, I have a unique index on two fields only when a third field is null, and I generate an ON CONFLICT clause based on that index. Do you see an easier way to add support for that without needing to add the new functionality that I added here?

@fnimick fnimick reopened this Jun 8, 2020
@fnimick fnimick force-pushed the unique-index-updateOnDuplicate branch 3 times, most recently from 482c603 to 23b1d0e Compare June 9, 2020 01:52
@fnimick
Copy link
Author

fnimick commented Jun 9, 2020

@papb I've now added postgres specific tests for this. Please let me know if my style of writing them is OK.

Adds options `upsertKeys` and `upsertIndex`. These options work with
sqlite as well as postgres.

This allows the use of a unique index for a `bulkCreate` with
`updateOnDuplicate` set. The unique index may be
a partial index.

Closes sequelize#11534, sequelize#11569
@fnimick fnimick force-pushed the unique-index-updateOnDuplicate branch from 23b1d0e to 42f64bf Compare June 9, 2020 14:27
@fnimick
Copy link
Author

fnimick commented Jun 9, 2020

I've now also added sqlite tests, since this feature is supported by sqlite as well, and have improved the documentation on the new options.

@fnimick
Copy link
Author

fnimick commented Jun 18, 2020

@papb is there anything I can do to move this forward? Thanks!

@malammar
Copy link

Would love to help out to get this done. It's critical for bulkCreate usage on Postgres.

@ramezhanna
Copy link

This PR is urgent to get bulk upsert work correctly on postgres

@CharlesEgan
Copy link

Agreed this is urgently needed. Happy to help resolving the conflicts so this can move forward.

@fnimick
Copy link
Author

fnimick commented Oct 27, 2020

Unfortunately this PR was not reviewed before the rewrite in Typescript was started, so not only are there many conflicts, some of the files I have changed no longer exist.

I asked in #12429 about the best strategy, but got no clear answer.

I would recommend doing a raw sql query for now - or using sequelize 5.21.1 with my patch, if you absolutely must have the ORM interface which matches this PR. There's no guarantee that this interface will be merged in though, so I would recommend raw queries instead. @CharlesEgan

https://gist.github.com/fnimick/313091df3ecc6c5e5f17be1e0950c33f

@sfalihi

This comment has been minimized.

@sdepold
Copy link
Member

sdepold commented Oct 24, 2021

Hey there :)

First of all: Thanks a bunch for your contribution to Sequelize! Much appreciated!
Second: Unfortunately we haven't had the chance to look into this ever since you created it. Sorry for that!

A couple of months ago, we have switched from master to main branch as our primary development branch and hence this PR is now outdated :(

If you still think this change is making sense, please consider recreating the PR against main. Thanks in advance and sorry for the additional work.

✌️

@github-actions github-actions bot added the stale label Nov 5, 2021
@WikiRik WikiRik removed the stale label Nov 15, 2021
@github-actions github-actions bot added the stale label Nov 30, 2021
@WikiRik
Copy link
Member

WikiRik commented Jan 31, 2022

Closing this since it is still against master. Can be reopened if that changes.

@WikiRik WikiRik closed this Jan 31, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
stale type: feature For issues and PRs. For new features. Never breaking changes.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Sqlite: bulkCreate with updateOnDuplicate fails when the model contains a composite key.
9 participants