Changeset 683 for trunk/docs


Ignore:
Timestamp:
Jan 1, 2016, 6:11:01 PM (4 years ago)
Author:
cito
Message:

Return rows as named tuples in pgdb

By default, we now return result rows as named tuples in pgdb.

Note that named tuples can be accessed like normal lists and tuples,
and easily converted to these. They can also be easily converted to
(ordered) dictionaries by calling row._asdict(). Therefore the need
for alternative Cursor types with different row types has been greatly
reduced, so I have simplified the implementation in the last revision
by removing the added Cursor classes and cursor() methods again,
leaving only the old row_factory method for customizing the returned
row types. I complemented this with a new build_row_factory method,
because different named tuple classes must be created for different
result sets, so a static row_factory method is not so appropriate.

Tests and documentation for these changes are included.

Location:
trunk/docs
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/docs/changelog.rst

    r681 r683  
    77- The supported versions are Python 2.6, 2.7, 3.3, 3.4 and 3.5.
    88- The supported PostgreSQL versions are 9.0, 9.1, 9.2, 9.3 and 9.4.
     9- The DB-API 2 module now always returns result rows as named tuples
     10  instead of simply lists as before. The documentation explains how
     11  you can restore the old behavior or use custom row objects instead.
    912- The names of the various types supported by the classic and DB-API 2
    1013  modules have been renamed to become simpler, more intuitive and in
  • trunk/docs/pgdb.rst

    r681 r683  
    191191------------------------------------
    192192
    193 .. method:: Connection.cusor()
     193.. method:: Connection.cursor()
    194194
    195195    Return a new cursor object using the connection
     
    200200This method returns a new :class:`Cursor` object that can be used to
    201201operate on the database in the way described in the next section.
     202
     203Attributes that are not part of the standard
     204--------------------------------------------
     205
     206.. note::
     207
     208   The following attributes are not part of the DB-API 2 standard.
     209
     210.. attribute:: cursor_type
     211
     212    The default cursor type used by the connection
     213
     214If you want to use your own custom subclass of the :class:`Cursor` class
     215with he connection, set this attribute to you custom cursor class. You will
     216then get your custom cursor whenever you call :meth:`Connection.cursor`.
    202217
    203218
     
    319334
    320335    :returns: the next row of the query result set
    321     :rtype: tuple or None
    322 
    323 Fetch the next row of a query result set, returning a single tuple,
    324 or ``None`` when no more data is available.
     336    :rtype: named tuple or None
     337
     338Fetch the next row of a query result set, returning a single named tuple,
     339or ``None`` when no more data is available. The field names of the named
     340tuple are the same as the column names of the database query as long as
     341they are valid Python identifiers.
    325342
    326343An :exc:`Error` (or subclass) exception is raised if the previous call to
     
    340357    :tpye keep: bool
    341358    :returns: the next set of rows of the query result
    342     :rtype: list of tuples
    343 
    344 Fetch the next set of rows of a query result, returning a list of tuples.
    345 An empty sequence is returned when no more rows are available.
     359    :rtype: list of named tuples
     360
     361Fetch the next set of rows of a query result, returning a list of named
     362tuples. An empty sequence is returned when no more rows are available.
     363The field names of the named tuple are the same as the column names of
     364the database query as long as they are valid Python identifiers.
    346365
    347366The number of rows to fetch per call is specified by the *size* parameter.
     
    371390
    372391    :returns: the set of all rows of the query result
    373     :rtype: list of tuples
    374 
    375 Fetch all (remaining) rows of a query result, returning them as list of tuples.
     392    :rtype: list of named tuples
     393
     394Fetch all (remaining) rows of a query result, returning them as list of
     395named tuples. The field names of the named tuple are the same as the column
     396names of the database query as long as they are valid Python identifiers.
     397
    376398Note that the cursor's :attr:`arraysize` attribute can affect the performance
    377399of this operation.
    378400
    379 row_factory -- process a row of the query result
    380 ------------------------------------------------
    381 
    382 .. method:: Cursor.row_factory(row)
    383 
    384     Process rows before they are returned
    385 
    386     :param tuple row: the currently processed row of the result set
    387     :returns: the transformed row that the cursor methods shall return
    388 
    389 Note that this method is not part of the DB-API 2 standard.
    390 
    391 You can overwrite this method with a custom row factory, e.g.
    392 if you want to return rows as dicts instead of tuples::
    393 
    394     class DictCursor(pgdb.Cursor):
    395 
    396         def row_factory(self, row):
    397             return {desc[0]:value
    398                 for desc, value in zip(self.description, row)}
    399 
    400     cur = DictCursor(con)
    401 
    402401arraysize - the number of rows to fetch at a time
    403402-------------------------------------------------
     
    408407
    409408This read/write attribute specifies the number of rows to fetch at a time with
    410 :meth:`Cursor.fetchmany`. It defaults to 1 meaning to fetch a single row
     409:meth:`Cursor.fetchmany`. It defaults to 1, meaning to fetch a single row
    411410at a time.
     411
     412Methods and attributes that are not part of the standard
     413--------------------------------------------------------
     414
     415.. note::
     416
     417   The following methods and attributes are not part of the DB-API 2 standard.
     418
     419.. method:: Cursor.row_factory(row)
     420
     421    Process rows before they are returned
     422
     423    :param tuple row: the currently processed row of the result set
     424    :returns: the transformed row that the fetch methods shall return
     425
     426This method is used for processing result rows before returning them through
     427one of the fetch methods. By default, rows are returned as named tuples.
     428You can overwrite this method with a custom row factory if you want to
     429return the rows as different kids of objects. This same row factory will then
     430be used for all result sets. If you overwrite this method, the method
     431:meth:`Cursor.build_row_factory` for creating row factories dynamically
     432will be ignored.
     433
     434Note that named tuples are very efficient and can be easily converted to
     435dicts (even OrderedDicts) by calling ``row._asdict()``. If you still want
     436to return rows as dicts, you can create a custom cursor class like this::
     437
     438    class DictCursor(pgdb.Cursor):
     439
     440        def row_factory(self, row):
     441            return {key: value for key, value in zip(self.colnames, row)}
     442
     443    cur = DictCursor(con)  # get one DictCursor instance or
     444    con.cursor_type = DictCursor  # always use DictCursor instances
     445
     446
     447.. method:: Cursor.build_row_factory()
     448
     449    Build a row factory based on the current description
     450
     451    :returns: callable with the signature of :meth:`Cursor.row_factory`
     452
     453This method returns row factories for creating named tuples. It is called
     454whenever a new result set is created, and :attr:`Cursor.row_factory` is
     455then assigned the return value of this method. You can overwrite this method
     456with a custom row factory builder if you want to use different row factories
     457for different result sets. Otherwise, you can also simply overwrite the
     458:meth:`Cursor.row_factory` method. This method will then be ignored.
     459
     460The default implementation that delivers rows as named tuples essentially
     461looks like this::
     462
     463    def build_row_factory(self):
     464        return namedtuple('Row', self.colnames, rename=True)._make
     465
     466.. attribute:: Cursor.colnames
     467
     468    The list of columns names of the current result set
     469
     470The values in this list are the same values as the *name* elements
     471in the :attr:`Cursor.description` attribute. Always use the latter
     472if you want to remain standard compliant.
     473
     474.. attribute:: Cursor.coltypes
     475
     476    The list of columns types of the current result set
     477
     478The values in this list are the same values as the *type_code* elements
     479in the :attr:`Cursor.description` attribute. Always use the latter
     480if you want to remain standard compliant.
    412481
    413482
     
    473542    Used to describe the ``oid`` column of PostgreSQL database tables
    474543
    475 The following more specific types are not part of the DB-API 2 standard:
     544.. note::
     545
     546  The following more specific types are not part of the DB-API 2 standard.
    476547
    477548.. class:: BOOL
Note: See TracChangeset for help on using the changeset viewer.