> 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