Friday, July 25, 2014

Re: Different objects returned when filtering with a ValuesListQuerySet


On Fri, Jul 25, 2014 at 11:36 PM, Marc Kirkwood <marc.kirkwood@talktopebble.co.uk> wrote:
When filtering a queryset with a ValuesListQuerySet instance in Django 1.6, different objects to that shown in the apparent list seem to be returned by the iterator.

An illustration of a head-scratching debug session is shown below:

(Pdb) latest
[4, 1]
(Pdb) keys.filter(pk__in=latest).values_list('pk')
[(3,), (1),)]
(Pdb) keys.filter(pk__in=[4, 1]).values_list('pk')
[(4,), (1),)]

Can anyone explain this behaviour to me? When I fully convert it with list(latest), normal service resumes.
I have a suspicion that it's because of the Postgres-aware order_by() and distinct() chain, in the queryset that latest was produced from.
 
It's difficult to say for certain without knowing details of all the moving parts, but I'm going to guess that the query that is producing latest isn't as consistent as you think it is.

In your debug session, statement 2 isn't "retrieve results that match statement 1", it's "retrieve results that match this subquery". That is, "latest" is being re-evaluated as a subquery in the second statement. If there's any order sensitivity in the query generating "latest", you're not guaranteed to get the same results. 

However, if you call list(latest), it ceases to be a subquery - it takes the cached results from the first statement and turns it into an IN [values] clause - effectively the same as statement 3.

If there are lots of order_by and distinct clauses, that might also affect exactly how the subquery is rolling out; it would be worth printing keys.filter(pk__in=latest).query to see exactly what is being executed.

Yours,
Russ Magee %-)

--
You received this message because you are subscribed to the Google Groups "Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-users+unsubscribe@googlegroups.com.
To post to this group, send email to django-users@googlegroups.com.
Visit this group at http://groups.google.com/group/django-users.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/CAJxq84-Vjw6Fe-0V%3DhYwznCvzzMxVPVCnQOUBkqj9rD-5HW1VA%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.

No comments:

Post a Comment