On Wed, 2007-10-31 at 11:09 -0400, George Vilches wrote:
> Stated simply:
> queryset.select_related().count() with no filter criteria generates a 
> wrong query across a ForeignKey relationship.
> 
> The problem: A QuerySet operation that involves a .count() across a 
> ForeignKey relationship does not actually join in the ForeignKey tables 
> to do the select_related().count(), unless you force it to use criteria 
> on the ForeignKey table.  If the ForeignKey match happens to be the 
> primary key in the foreign table as well (not in the example), then the 
> filter can't be on it, because QuerySet seems to optimize out the JOIN 
> (less important but possibly helpful info).
> 
> 
> Example (create a new Django app and paste this right in, and then do 
> the rest from the shell):
> 
> Assume I have two models in models.py:
> 
> class Item(models.Model):
>      name = models.CharField(max_length=100)
>      group = models.IntegerField()
> 
> class Assembly(models.Model):
>      desc = models.CharField(max_length=100)
>      item_group = models.ForeignKey(Item, to_field='group')
> 
> 
> and they are populated with data like so:
> 
> from qs.models import *
> Item.objects.create(name='item1', group=1)
> Item.objects.create(name='item2', group=1)
> Item.objects.create(name='item3', group=1)
> Item.objects.create(name='item4', group=2)
> Item.objects.create(name='item5', group=2)
> Item.objects.create(name='item6', group=2)
> Assembly.objects.create(desc='as1', item_group_id=1)
> Assembly.objects.create(desc='as1', item_group_id=2)
> 
> 
> 
> Now, run these commands (I've included output from the Python interpreter):
> 
> 
>  >>> Assembly.objects.select_related()
> [<Assembly: Assembly object>, <Assembly: Assembly object>, <Assembly: 
> Assembly object>, <Assembly: Assembly object>, <Assembly: Assembly 
> object>, <Assembly: Assembly object>]
>  >>> len(Assembly.objects.select_related())
> 6
>  >>> Assembly.objects.select_related().count()
> 2L
> 
> 
> Since I'm using select_related(), I would expect it to follow the INNER 
> JOINs to do the .count().  I can force it to use the JOINs by doing this:

This is where you've made a mistake (aside from the to_field problem
Karen pointed out). Your assumption is wrong. select_related() is only
an optimisation as far as loading the data form the database. It should
*never* change the result of a quantitative query like this. If it does,
it would be a bug.

Regards,
Malcolm

-- 
I intend to live forever - so far so good. 
http://www.pointy-stick.com/blog/


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

Reply via email to