I think that changing the return value of fetchall should be
considered breaking backward compatibility. Moreover it would make
postgresql behave differently than the other database backends.

On Apr 1, 7:22 am, David Niergarth <[email protected]> wrote:
> > Is it really backward compatible? Have you tried?
>
> I tried basic integer indexing and slicing, which work as expected, as
> does the dictionary interface. I just went through all the scenarios I
> could think of and found two differences with DictCursor.
>
>     1) Extended slicing fails with an exception (e.g., row[2:5:2] or
> row[::-1]).
>     2) DictCursor objects have the unfortunate list behavior that they
> can't be used directly for string interpolation, whereas tuples can.
>
> --David
>
> Here are the details. Starting with a simple query,
>
>     >>> import psycopg2
>     >>> query = ('select id, first_name, last_name, email, password, '
>     ...          'registration_key from auth_user;')
>
> check the default behavior.
>
>     >>> conn = psycopg2.connect('')
>     >>> cursor = conn.cursor()
>     >>> cursor.execute(query)
>     >>> rs = cursor.fetchall()
>     >>> row = rs[0]
>     >>> row
>     (1, 'Joe', 'Demo', '[email protected]',
> '4352cd32e514b98bf6d88ccde0775bf3', '')
>
> Rows are plain tuples by default.
>
>     >>> type(row)
>     <type 'tuple'>
>     >>> default_row = row  # preserve the row for later
>
>  Now try with DictConnection.
>
>     >>> import psycopg2.extras
>     >>> conn = psycopg2.extras.DictConnection('')
>     >>> cursor = conn.cursor()
>     >>> cursor.execute(query)
>     >>> rs = cursor.fetchall()
>     >>> row = rs[0]
>     >>> type(row)
>     <class 'psycopg2.extras.DictRow'>
>
> Results are now DictRows instead of tuples. DictRows repr like lists.
>     >>> row
>     [1, 'Joe', 'Demo', '[email protected]',
> '4352cd32e514b98bf6d88ccde0775bf3', '']
>
> And they have list methods. (Tuples have no non-special methods so
> this seems ok.
>
>     >>> row.index('Joe')
>     1
>
> They convert nicely to other builtins.
>
>     >>> list(row)
>     [1, 'Joe', 'Demo', '[email protected]',
> '4352cd32e514b98bf6d88ccde0775bf3', '']
>     >>> tuple(row)
>     (1, 'Joe', 'Demo', '[email protected]',
> '4352cd32e514b98bf6d88ccde0775bf3', '')
>     >>> dict(row)
>     {'first_name': 'Joe', 'last_name': 'Demo', 'id': 1, 'password':
> '4352cd32e514b98bf6d88ccde0775bf3', 'registration_key': '', 'email':
> '[email protected]'}
>
> Integer indexing and len() works.
>
>     >>> row[0], row[1], row[2], row[3], row[4], row[5]
>     (1, 'Joe', 'Demo', '[email protected]',
> '4352cd32e514b98bf6d88ccde0775bf3', '')
>     >>> len(row)
>     6
>
> They also have a dict interface.
>
>     >>> row.keys()
>     ['first_name', 'last_name', 'email', 'password',
> 'registration_key', 'id']
>     >>> row['first_name'], row['last_name'], row['id']
>     ('Joe', 'Demo', 1)
>
> Slicing works as expected.
>
>     >>> row[:3]
>     [1, 'Joe', 'Demo']
>     >>> row[-3:]
>     ['[email protected]', '4352cd32e514b98bf6d88ccde0775bf3', '']
>     >>> row[2:5]
>     ['Demo', '[email protected]', '4352cd32e514b98bf6d88ccde0775bf3']
>
> Hmmm, extended slicing fails (Strike 1)...
>
>     >>> row[2:5:-1]
>     Traceback (most recent call last):
>     File "<stdin>", line 1, in <module>
>     File "/usr/lib/python2.5/site-packages/psycopg2/extras.py", line
> 110, in __getitem__
>         x = self._index[x]
>     TypeError: unhashable type
>     >>> row[2:5:1]
>     Traceback (most recent call last):
>     File "<stdin>", line 1, in <module>
>     File "/usr/lib/python2.5/site-packages/psycopg2/extras.py", line
> 110, in __getitem__
>         x = self._index[x]
>     TypeError: unhashable type
>
> but it works for regular tuples.
>
>     >>> default_row[2:5:1]
>     ('Demo', '[email protected]', '4352cd32e514b98bf6d88ccde0775bf3')
>     >>> default_row[2:5:-1]
>     ()
>
> Another problem is the difference between tuples and lists when doing
> string interpolation. String interpolation requires a tuple and fails
> with a list. For example,
>
>     >>> '%s %s' % ('a', 'b')
>     'a b'
>
>     >>> '%s %s' % ['a', 'b']
>     Traceback (most recent call last):
>     File "<stdin>", line 1, in <module>
>     TypeError: not enough arguments for format string
>
> The DictCursor fails with string interpolation, just like a list
> (Strike 2),
>
>     >>> '%s %s %s %s %s %s' % row
>     Traceback (most recent call last):
>     File "<stdin>", line 1, in <module>
>     TypeError: not enough arguments for format string
>
> but works when wrapped with tuple().
>
>     >>> '%s %s %s %s %s %s' % tuple(row)
>     '1 Joe Demo [email protected] 4352cd32e514b98bf6d88ccde0775bf3 '
>
> It was pretty easy to find two ways DictCursor wouldn't be completely
> backward compatible. It's probably safe to bet there are other edge
> cases that could be found.
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"web2py Web Framework" 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/web2py?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to