Opened 13 years ago

Last modified 9 years ago

#16891 closed New feature

[patch] queryset delete should return number of rows matched — at Version 14

Reported by: Steven Cummings Owned by: Steven Cummings
Component: Database layer (models, ORM) Version: dev
Severity: Normal Keywords:
Cc: Sergey Kolosov, dev@…, Zach Borboa 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 Carl Meyer)

Splitting this off from ticket #16549...

Deep in the bowels of django.db the rows modified value from update and delete queries is ignored and discarded. For reasons discussed on ticket 16549, it would sometimes be useful to have access to that value.

Objective of this bug is to passively return rows-modified up through the call-stack and, ultimately, hopefully from each of:

  • Model.save()
  • Model.delete()
  • QuerySet.update()
  • QuerySet.delete()

with consideration for transaction control/mgmt.

Update from comment thread: queryset update already returns rows-matched (and this can't be changed to rows-changed without breaking other things). So it is only deletes that need this change.

Change History (15)

comment:1 by Steven Cummings, 13 years ago

Owner: changed from nobody to Steven Cummings

Claiming to work on.

comment:2 by Carl Meyer, 13 years ago

Component: UncategorizedDatabase layer (models, ORM)
Triage Stage: UnreviewedAccepted
Type: UncategorizedNew feature

comment:3 by Steven Cummings, 13 years ago

Finally got around to these simple changes:

If the core devs approve of these changes I can get to work on creating the proper patch for SVN and add doc changes.

comment:4 by Anssi Kääriäinen, 13 years ago

An idea for the save() patch: return UPDATED, INSERTED, or None instead of 1/0. You could still do if obj.save(): (matches both UPDATED and INSERTED) but if need be, you could see if the object was indeed updated or inserted. The value would be the "outermost" value for multitable inherited models.

I wonder if it would be a good idea to return the amount of deletions per object type when deleting? I see at least three choices:

  • Just a dict model_class -> delete count, for example in your test case this would be {R:1, S:2, T:2}
  • Tuple total_objects_deleted, abovementioned dict: Example: (5, {R:1, S:2, T:2})
  • Tuple amount_of_outer_objs, abovementioned dict: Example: (1, {R:1, S:2, T:2})

To me it seems these could be useful, especially the #2 format. This information can be gotten nearly for free. The inconvenience here is that you can't do if obj.delete(): as (0, {}) isn't False. Maybe this could be postponed for later inclusion with kwarg with_counts=True or something. Or maybe there is just no use case for this.

comment:5 by Steven Cummings, 13 years ago

In case anybody is paying more attention here than on django-dev, I made an update to roll the changes back to just the internal query classes for now:

by Steven Cummings, 13 years ago

Attachment: delete_counts.patch added

Patch to changes so far from git clone

comment:6 by Steven Cummings, 13 years ago

Has patch: set

I haven't gotten much feedback on this ticket, but what I've gotten so far has convinced me to back off of any changes to the base Model API. UpdateQuery already returned rowcounts, which means that only DeleteQuery needed updating. So, the patch is pretty tiny as you can see.

comment:7 by Steven Cummings, 13 years ago

Summary: Delete/update should return number of rows modified[patch] Delete/update should return number of rows modified

Updating summary

comment:8 by Aymeric Augustin, 13 years ago

#17435 was a duplicate.

in reply to:  6 comment:9 by Sergey Kolosov, 13 years ago

Cc: Sergey Kolosov added

Replying to estebistec:

I haven't gotten much feedback on this ticket, but what I've gotten so far has convinced me to back off of any changes to the base Model API. UpdateQuery already returned rowcounts, which means that only DeleteQuery needed updating. So, the patch is pretty tiny as you can see.

Since QuerySet.update returns not the number of rows affected, but the number of rows matched (as I’ve described it in #17435), I believe the UpdateQuery still needs to be patched.

comment:10 by Steven Cummings, 13 years ago

Yeah, if there are no objections to rolling #17435 into this bug, I'll go back in and add QuerySet.update to the patch.

comment:11 by Karen Tracey, 13 years ago

No, I don't think update() can be switched to start returning the actually-modified row count rather than matched row count. See #17435 for why, the fix for that one is to clarify the doc.

in reply to:  11 comment:12 by Steven Cummings, 13 years ago

Replying to kmtracey:

No, I don't think update() can be switched to start returning the actually-modified row count rather than matched row count. See #17435 for why, the fix for that one is to clarify the doc.

So I need to take a closer look here too and see if the delete() counts can mirror update() in that way.

comment:13 by anonymous, 13 years ago

Patch needs improvement: set

comment:14 by Carl Meyer, 13 years ago

Description: modified (diff)
Summary: [patch] Delete/update should return number of rows modified[patch] queryset delete should return number of rows matched
Note: See TracTickets for help on using tickets.
Back to Top