On Sun, May 31, 2009 at 2:36 PM, phildev7...@gmail.com <
phildev7...@gmail.com> wrote:

>
> Hi there,
>
> I am having a puzzling issue with something that should be pretty
> straightforward. I have a variable called "sznames" which results from
> a .values() request performed on a queryset.
>

Note values() applied to a QuerySet will turn it into a ValuesQuerySet, not
a list.  A ValuesQuerySet will still have the lazy evaluation characteristic
of a QuerySet, and it will still use SQL statements with LIMIT/OFFSET
applied when you index into it.  I suspect that is what you are running
into.


> This "sznames" variable is successfully filled with dictionaries -
> three dictionaries in the test I am running. When i try to access
> those dictionaries with sznames[0], sznames[1] and sznames[2], the
> dictionary returned is not the right one:
>
> let's assume:
>
> sznames contains [{'mykey': valueA}, {'mykey': valueB}, {'mykey':
> valueC}]
>
> then:
> sznames[0] returns {'mykey': valueC}
> sznames[1] returns {'mykey': valueB}
> sznames[2] returns {'mykey': valueC}
>

Printing the values of sznames will evaluate the ValuesQuerySet and you'll
see the full set of results.  Indexing into sznames will also evaluate the
ValuesQuerySet, only with limit/offset applied, to get exactly one row.  If
there is no specified unique ordering on the ValuesQuerySet, then there is
no guarantee that the results from indexing 0,1,2 will match the results you
see in the full set.  It's dependent on the particular DB what row is
returned when OFFSET n LIMIT m is specified and there is no unique order
specified -- PostgreSQL is the one that most often returns "surprising"
answers here.

You can see that indexing generates additional SQL queries by examining
what's logged in django.db.connection.queries, assuming you have DEBUG set
to True.  In this case there is a unique order specified by default for this
particular model (and the DB is not PostgreSQL), so the session doesn't
illustrate the problem but it does show how you can see the queries in your
case that are likely the cause of the problem:

Python 2.5.2 (r252:60911, Oct  5 2008, 19:24:49)
[GCC 4.3.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> from crossword.models import Publishers
>>> from django.db import connection
>>> x = Publishers.objects.filter(Editor="Will Shortz").values('ShortName')
>>> type(x)
<class 'django.db.models.query.ValuesQuerySet'>
>>> len(connection.queries)
0
>>> x
[{'ShortName': u'ACPT'}, {'ShortName': u'NYT'}, {'ShortName': u'NYT2'}]
>>> len(connection.queries)
1
>>> x[1]
{'ShortName': u'NYT'}
>>> len(connection.queries)
2
>>> x2 = list(x)
>>> len(connection.queries)
3
>>> x2[0]
{'ShortName': u'ACPT'}
>>> len(connection.queries)
3
>>> import pprint
>>> pprint.pprint(connection.queries)
[{'sql': u'SELECT `Publishers`.`Short Name` FROM `Publishers` WHERE
`Publishers`.`Editor` = Will Shortz ) ORDER BY `Publishers`.`Publisher` ASC
LIMIT 21',
   'time': '0.001'},
 {'sql': u'SELECT `Publishers`.`Short Name` FROM `Publishers` WHERE
`Publishers`.`Editor` = Will Shortz ) ORDER BY `Publishers`.`Publisher` ASC
LIMIT 1 OFFSET 1',
   'time': '0.000'},
 {'sql': u'SELECT `Publishers`.`Short Name` FROM `Publishers` WHERE
`Publishers`.`Editor` = Will Shortz ) ORDER BY `Publishers`.`Publisher`
ASC',
  'time': '0.000'}]
>>>

If you are going to be accessing the whole set of results, turning it into a
list before indexing into it is likely the easiest way to solve the problem
you are seeing.

Karen

--~--~---------~--~----~------------~-------~--~----~
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 
django-users+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/django-users?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to