Lighthouse has a new layout. Prefer the old one? Return to the old layout, and switch back any time from the link at the top of each page.

This project is archived and is in readonly mode.

Row type is not the expected one, depending on the used factory connection

#85

Depending on the connection factory, the row type, when returned in an iterator way (curs.next()) is not the right one, or is bugged.

  • psycopg2.extras.RealDictConnection

    • cursor.next() : OK
    • cursor.fetch*() : OK
  • psycopg2.extras.DictConnection

    • cursor.next() : KO - the returned row can't be accessed in a dict-fashion.
    • cursor.fetch*() : OK
>>> row = curs.next()
>>> type(row)
<class 'psycopg2.extras.DictRow'>
>>> row['id']
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.6/dist-packages/psycopg2/extras.py", line 155, in __getitem__
    x = self._index[x]
KeyError: 'id'
>>> row.keys()
[]
  • psycopg2.extras.NamedTupleConnection
    • cursor.next() : KO - the returned row type is a tuple, not a named tuple.
    • cursor.fetch*() : OK
>>> row = curs3.next()
>>> type(row)
<type 'tuple'>
>>> row.id
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'tuple' object has no attribute 'id'
  • psycopg2._psycopg.connection
    • cursor.next() : OK
    • cursor.fetch() : OK

rel-2.4.4
os-linux (Ubuntu 10.10)

Reported by Samuel PHAN · December 21st, 2011 @ 10:12 AM

State: invalid
Milestone: none
Assigned to: nobody

Activity

  1. Daniele Varrazzo
    Daniele Varrazzo
    • State changed from new to invalid

    cursor.next() is not part of the public interface, but an implementation detail: the cursor is iterable (you can call iter() on it), the fact it is also an iterator (exposing next()) is an implementation detail which may also change in the future.

    The artefacts you are seeing are due to __iter__ not being called before next(): the latter should only be called as part of the iteration protocol; the only well defined behaviour is that:

    cur = ...
    cur.execute(SQL)
    i = iter(cur)
    i.next()
    

    works as expected for any cursor type.

    The fact next() is not called __next__(), thus resembling a public method, has been acknowledged as a python design mistake: see http://www.python.org/dev/peps/pep-3114/.

    January 10th, 2012 @ 02:10 AM