Opened 3 years ago

Last modified 19 months ago

#23646 new New feature

query set sql update to change different values by different keys (include django-bulk-update in core)

Reported by: Brillgen Developers Owned by: nobody
Component: Database layer (models, ORM) Version: 1.9
Severity: Normal Keywords:
Cc: Triage Stage: Accepted
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description (last modified by Brillgen Developers)

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 (6)

comment:1 Changed 3 years ago by Brillgen Developers

Description: modified (diff)

comment:2 Changed 3 years ago by Russell Keith-Magee

Resolution: wontfix
Status: newclosed

The link you've provided suggests that the ORM example you've provided would be interpreted as:

UPDATE books_book 
SET 
 price = 10 where pk = 1,
 price = 25 where pk = 2

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:

Books.objects.all().update('pk', values={'pk': 1, 'price': 10}, {'pk': 2, 'price': 25})

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:

Book.objects.filter(pk=1).update(price=10)
Book.objects.filter(pk=2).update(price=25)

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).

comment:3 Changed 3 years ago by Shai Berger

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 Changed 19 months ago by Brillgen Developers

Resolution: wontfix
Status: closednew

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 Changed 19 months ago by Brillgen Developers

Description: modified (diff)
Summary: query set sql update to change different values by different keysquery set sql update to change different values by different keys (include django-bulk-update in core)
Version: 1.71.9

comment:6 Changed 19 months ago by Tim Graham

Triage Stage: UnreviewedAccepted

Tentatively accepting, pending discussion on the DevelopersMailingList to approve the idea and API.

Note: See TracTickets for help on using tickets.
Back to Top