Opened 10 years ago
Last modified 3 years ago
#23646 closed New feature
query set sql update to change different values by different keys (include django-bulk-update in core) — at Version 5
Reported by: | Brillgen Developers | Owned by: | nobody |
---|---|---|---|
Component: | Database layer (models, ORM) | Version: | 1.9 |
Severity: | Normal | Keywords: | |
Cc: | Tom Forbes | Triage Stage: | Accepted |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description (last modified by )
Update
django-bulk-upate (https://github.com/aykut/django-bulk-update) which could/should be integrated into django core since we have a bulk_create and this corresponds well with the save (could be called bulk save if it makes sense). App works with an identical api to bulk_create and so should be a good candidate to be considered for inclusion in core.
Database backends like Postgresql support doing multiple value update for the same field in different rows using a single update query. Please see this sample below:
http://stackoverflow.com/questions/18797608/update-multiple-rows-in-same-query-using-postgresql
Example:
Currently:
Books.objects.all().update(price=10)
Proposed (syntax can vary):
Books.objects.all().update({'pk': 1, 'price': 10}, {'pk': 2, 'price': 25}])
Idea is to do it in sql for performance reasons but still use the ORM and not use a raw database connection.
However, such an interface is not exposed via the Django ORM. Would this be accepted as a patch? if so, would a list dictionary with the various fields:values to be updated be a good way to provide the input to ORM
Change History (5)
comment:1 by , 10 years ago
Description: | modified (diff) |
---|
comment:2 by , 10 years ago
Resolution: | → wontfix |
---|---|
Status: | new → closed |
comment:3 by , 10 years ago
On an old project, ~10 years ago and not Django based, we used a "bulk update" procedure that did:
1) Bulk-insert the new records into a temporary table
2) update in one statement using a join (SQL Server lets you do that)
On hundreds of records, this was significantly faster than updating one-by-one (I no longer have access to any hard data, and it's irrelevant anyways).
Anyway, I suspect a better API would involve passing a collection of objects and selecting just the fields to update: Book.objects.update_many(books, 'price')
comment:4 by , 9 years ago
Resolution: | wontfix |
---|---|
Status: | closed → new |
Reopening even though it was closed by a core team member because another core member has reported the significant performance improvement.
Also, there is an app called django-bulk-upate (https://github.com/aykut/django-bulk-update) which could/should be integrated into django core since we have a bulk_create and this corresponds well with the save (could be called bulk save if it makes sense). App works with an identical api to bulk_create and so should be a good candidate to be considered for inclusion in core.
comment:5 by , 9 years ago
Description: | modified (diff) |
---|---|
Summary: | query set sql update to change different values by different keys → query set sql update to change different values by different keys (include django-bulk-update in core) |
Version: | 1.7 → 1.9 |
The link you've provided suggests that the ORM example you've provided would be interpreted as:
So... what in the ORM statement identifies which column is to be used in the
WHERE
clause, and which is to be updated? As currently expressed, it's ambiguous. You'd need to modify the statement to be something like:which nominates which values in the data are for the select.
However, even with those changes, I'm not sure I see why doing this as a single statement version would be preferable to:
AFAIK, it's no faster on the database side (although feel free to prove me wrong on that), and I don't find a "one liner API" especially expressive or clear for this feature.
For that reason, I'm marking this wontfix. If you feel the idea is still worth pursuing, feel free to start a discussion on django-developers and make your case. (I know you started one on django-users, but in this case, you need the eyeballs from -dev).