Opened 3 years ago

Closed 2 years ago

#32381 closed New feature (fixed)

Include number of rows matched in bulk_update() return value

Reported by: Chris Jerdonek Owned by: Abhyudai
Component: Database layer (models, ORM) Version: dev
Severity: Normal Keywords: bulk_update
Cc: Tom Forbes, Diego Lima Triage Stage: Ready for checkin
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: yes UI/UX: no

Description

Currently, bulk_update() returns None, unlike update(), which returns the number of rows matched.

It looks like it would be easy to add the same functionality to bulk_update() since bulk_update() simply calls update() repeatedly:
https://github.com/django/django/blob/2b4b6c8af0aae8785bc1347cf1be2e8e70fd5ff3/django/db/models/query.py#L568
I.e. the return values could simply be added and returned.

Change History (24)

comment:1 Changed 3 years ago by Chris Jerdonek

Also, if this feature is okayed, maybe the number could be returned in a way that would permit other useful numbers to be added to the return value in a backwards-compatible way later on. For example, the number could be returned as a property of a named tuple with one property. That way, if a new value is requested in the future, it could be added by adding a new property to the named tuple.

comment:2 Changed 3 years ago by Mariusz Felisiak

Cc: Tom Forbes added
Triage Stage: UnreviewedAccepted

Also, if this feature is okayed, maybe the number could be returned in a way that would permit other useful numbers to be added to the return value in a backwards-compatible way later on. For example, the number could be returned as a property of a named tuple with one property. That way, if a new value is requested in the future, it could be added by adding a new property to the named tuple.

Do you have any specific statistics in mind?

comment:3 Changed 3 years ago by Chris Jerdonek

Thanks.

Do you have any specific statistics in mind?

Not especially, but more because I don't know what might be available. The only things that occur to me right now are things like the number of queries made, and the batch size used for the function call. More usefully, though, if update() were ever to grow the ability to report not just the number of rows matched but also the number of rows changed, that would definitely be of interest.

comment:4 Changed 3 years ago by Simon Charette

More usefully, though, if update() were ever to grow the ability to report not just the number of rows matched but also the number of rows changed, that would definitely be of interest.

Given that would likely require a signature change to update if we ever want to support it I think that making bulk_update return the sums of its updates should be good enough for now.

comment:5 Changed 3 years ago by Tom Forbes

I would second that: it’s good to be future proof, but we’re somewhat locked in to the current returned result due to update. Let’s just make it return the updated rows, which seems like a simple and sensible change.

comment:6 Changed 3 years ago by Tom Forbes

Easy pickings: set

comment:7 Changed 3 years ago by Manav Agarwal

Owner: changed from nobody to Manav Agarwal
Status: newassigned

comment:8 Changed 3 years ago by Tim McCurrach

I took a look at this yesterday and due to the way bulk_update treats duplicates in objs this might not be quite so straight forward as simply summing the returned values from repeated update() calls. Duplicates split between batches will be counted twice.

See https://code.djangoproject.com/ticket/32388

comment:9 Changed 3 years ago by Chris Jerdonek

There is now an (accepted) issue #32406 to make update() return something different. Given that, might it make sense to reconsider making bulk_update() future-proof now?

comment:10 Changed 3 years ago by Simon Charette

update will keep returning int unless returning is specified otherwise it would break backward compatibility.

Can't this ticket be dedicated to having bulk_update returning int when returning is not specified?

I don't see what needs to be made here to make bulk_update future proof? How does making bulk_update -> int prevent us from having bulk_update(returning) -> list match the signature of update(returning) -> list in the future?

comment:11 Changed 3 years ago by bhavikabadjate901

Owner: changed from Manav Agarwal to bhavikabadjate901

comment:12 Changed 3 years ago by bhavikabadjate901

assign to bhavikabadjate901

comment:13 in reply to:  4 Changed 3 years ago by Diego Lima

Cc: Diego Lima added
Owner: changed from bhavikabadjate901 to Diego Lima

Due to inactivity, I'm claiming this ticket. bhavikabadjate901 please come forward if you have done any work on this!

I'm taking the simplest approach first, which is bulk_update -> int. As stated by Simon Charette:

I think that making bulk_update return the sums of its updates should be good enough for now.

and Tom Forbes:

Let’s just make it return the updated rows

Then, I'll stop and think a bit more about Chris Jerdonek's future-proofing and Tim McCurrach's duplicate edge case.

comment:14 Changed 3 years ago by Diego Lima

Has patch: set

comment:15 Changed 3 years ago by Nick Pope

Needs documentation: set

comment:16 Changed 3 years ago by Nick Pope

Needs documentation: unset

comment:17 Changed 3 years ago by Diego Lima

PR ready for review at https://github.com/django/django/pull/14125. I did not handle duplicates, and did not future-proof bulk_update.

I'm keeping an eye on #32406. If it gets patched, I'll update the returned value on bulk_update. If we pin down an API that is generally agreed upon, I might claim that ticket as well.

comment:18 Changed 3 years ago by Mariusz Felisiak

Needs tests: set
Patch needs improvement: set

comment:19 Changed 2 years ago by Abhyudai

Owner: changed from Diego Lima to Abhyudai

comment:20 Changed 2 years ago by Abhyudai

comment:21 Changed 2 years ago by Mariusz Felisiak

Needs tests: unset
Patch needs improvement: unset

comment:22 Changed 2 years ago by Mariusz Felisiak

Patch needs improvement: set

comment:23 Changed 2 years ago by Mariusz Felisiak

Patch needs improvement: unset
Triage Stage: AcceptedReady for checkin

comment:24 Changed 2 years ago by Mariusz Felisiak <felisiak.mariusz@…>

Resolution: fixed
Status: assignedclosed

In cd12429:

Fixed #32381 -- Made QuerySet.bulk_update() return the number of objects updated.

Co-authored-by: Diego Lima <diego.lima@…>

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