Karen Tracey wrote:
> On 10/31/07, *George Vilches* <[EMAIL PROTECTED] 
> <mailto:[EMAIL PROTECTED]>> wrote:
> 
>     Or (I just saw your follow-up e-mail), is all of this a moot point since
>     something like this is going to be made totally invalid in the future?
> 
> 
> That's it.  Targeting a non-unique column in a ForeignKey field is 
> invalid.  It's invalid now, and will continue to be invalid.  The 
> difference is that it's not caught and flagged as an error now, and will 
> be when queryset-refactor gets merged into trunk. 
> 
> If you can whittle down your real problem to an example that does not 
> include this kind of invalid relationship (you said you are actually 
> using OneToOne fields?) maybe we could make some progress on 
> understanding/solving the real issue you are facing.

Here's an example that's a lot closer to home:

class Person(models.Model):
     name = models.CharField(max_length=100)
     status = models.IntegerField()

class PersonInfo(models.Model):
     person = models.OneToOneField(Person)
     phone = models.CharField(max_length=10)



 >>> from qs.models import *
 >>> Person.objects.create(name='user1', status=1)
<Person: Person object>
 >>> PersonInfo.objects.create(person_id=1, phone='111')
<PersonInfo: PersonInfo object>
 >>> PersonInfo.objects.create(person_id=99, phone='222')
<PersonInfo: PersonInfo object>

Yes, I know.  At this point we've added a PersonInfo that doesn't map to 
an existing person (id=99).

If at this point you're saying, "well that's stupid", I would ask you to 
point out where it says that a OneToOneField has any sort of forced 
referential integrity across the relationship (it most definitely is not 
generating constraints like the unique ForeignKey does).  I don't think 
it is a requirement, and would ask that you take the rest of this 
example in that spirit.


 >>> PersonInfo.objects.count()
2L
 >>> PersonInfo.objects.filter(person__id__gte=-1).count()
2L
 >>> PersonInfo.objects.filter(person__status__gte=-1).count()
1L

So the filter has to be on a non-related field in order to get the query 
to force the INNER JOIN and not optimize the result out.

More importantly, I'm getting different counts, and the reasoning seems 
to be based on an internal optimization.  That seems like a bug to me, 
I've made an effort to get a fake filter on the other table, and am 
still denied the accurate count.

What can I do to get the JOIN without having to also generate a (very 
slow when data sets are large) useless WHERE clause?



---


Someone might suggest that I do the selection from the POV of Person: 
Person.objects.filter(personinfo__...).  This is no good because I need 
to use the data from both Person and PersonInfo (I didn't put the 
select_related() in here for clarity's sake), and OneToOneFields don't 
work in the opposite direction, so I'd get a bunch of extra queries, one 
for each instance of Person returned (to get the PersonInfo bits).  The 
intention here is for reporting, and that returns a lot of rows, so I 
need to select on the relationship in the direction that caches the most 
data.

If OneToOneFields worked in both directions from the point of view of 
select_related(), which seems like a reasonable assumption, then pretty 
much this entire e-mail would not be a problem.  Malcolm, is this 
something that might be happening in qs-rf, having a OneToOneField that 
will follow in both directions?  We have a setup that looks like this: 
User is the base class, and then Member, MemberInfo, MemberData, and 
about 5 others all have OneToOneFields to User.  We would *LOVE* to be 
able to do User.select_related(depth=2) and get all those relations in a 
single query.  Right now, you can at most 2 tables/models worth of data 
with a single query, and all the other model instances that are touched 
result in an extra query.  Yuck. :)


Thanks,
George

--~--~---------~--~----~------------~-------~--~----~
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