On 27 heinä, 08:15, Jeremy Dunck <[email protected]> wrote:
> I have 2 models:
>
> class District(Model):
>   pass
>
> class Voter(Model):
>    districts = ManyToManyField(District)
>
> Sometimes I want to reset the m2m list:
>
> voter.districts = other_districts
>
> I noticed that this uses ManyRelatedManager._clear_items, which, among
> other things, boils down to:
>
> voter.districts.through._default_manager.filter(voter_id=voter.pk).delete()
>
> I would have expected something along the lines of :
>
> DELETE FROM `api_voter_districts` WHERE `voter_id` = 1
>
> But instead it's 2 queries:
>
> SELECT `api_voter_districts`.`id`, `api_voter_districts`.`voter_id`,
> `api_voter_districts`.`district_id` FROM `api_voter_districts` WHERE
> `api_voter_districts`.`voter_id` = 1
>
> DELETE FROM `api_voter_districts` WHERE `id` IN (2, 3, 4, 5, 6,...)
>
> Was it intentional to take 2 queries?  That is, is there a use case
> where avoiding the single DELETE query is preferable?

To me it seems there is no reason to do two queries in delete if the
following conditions hold:
  - there are no signals sent for the deleted objects
  - the delete does not cascade further (actually you don't need to
collect even in this case - you can do the cascade query completely in
the DB without fetching the IDs first).

For automatic M2M tables the above conditions always hold, but it is
not guaranteed if you are using the "through" argument.

To me it seems the correct fix is checking the above conditions. If
they hold, issue immediate delete query, if not, you need to collect
the objects, then delete. Doing the delete in single query can be a
huge win if you are deleting a lot of objects in one go. Actually, if
you are deleting too many objects, you will likely go OOM.

I am not objecting fixing this just for automatic m2m tables if
checking the conditions mentioned above turns out to be complicated.

 - Anssi

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en.

Reply via email to