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

