Author: cito
Date: Wed Dec 30 17:39:53 2015
New Revision: 681
Log:
Let cursor.description return named tuples
Modified:
trunk/docs/changelog.rst
trunk/docs/pgdb.rst
trunk/module/pgdb.py
trunk/module/tests/test_dbapi20.py
Modified: trunk/docs/changelog.rst
==============================================================================
--- trunk/docs/changelog.rst Wed Dec 30 16:56:42 2015 (r680)
+++ trunk/docs/changelog.rst Wed Dec 30 17:39:53 2015 (r681)
@@ -11,6 +11,10 @@
line with the names used in the DB-API 2 documentation.
Since the API provides objects of these types only by the use of
constructor functions, this should not cause any incompatibilities.
+- The tty parameter and attribute of database connections has been
+ removed since it is not supported any more since PostgreSQL 7.4.
+- The 7-tuples returned by the description attribute of a pgdb cursor
+ are now named tuples, i.e. their elements can be also accessed by name.
Version 4.2
-----------
Modified: trunk/docs/pgdb.rst
==============================================================================
--- trunk/docs/pgdb.rst Wed Dec 30 16:56:42 2015 (r680)
+++ trunk/docs/pgdb.rst Wed Dec 30 17:39:53 2015 (r681)
@@ -224,19 +224,21 @@
.. attribute:: Cursor.description
- This read-only attribute is a sequence of 7-item sequences.
+ This read-only attribute is a sequence of 7-item named tuples.
- Each of these sequences contains information describing one result column:
+ Each of these named tuples contains information describing
+ one result column:
- - *name*
- - *type_code*
- - *display_size*
- - *internal_size*
- - *precision*
- - *scale*
- - *null_ok*
+ - *name*
+ - *type_code*
+ - *display_size*
+ - *internal_size*
+ - *precision*
+ - *scale*
+ - *null_ok*
- Note that *precision*, *scale* and *null_ok* are not implemented.
+ Note that *display_size*, *precision*, *scale* and *null_ok*
+ are not implemented.
This attribute will be ``None`` for operations that do not return rows
or if the cursor has not had an operation invoked via the
Modified: trunk/module/pgdb.py
==============================================================================
--- trunk/module/pgdb.py Wed Dec 30 16:56:42 2015 (r680)
+++ trunk/module/pgdb.py Wed Dec 30 17:39:53 2015 (r681)
@@ -48,7 +48,8 @@
cursor.description # returns information about the columns
# [(column_name, type_name, display_size,
# internal_size, precision, scale, null_ok), ...]
- # Note that precision, scale and null_ok are not implemented.
+ # Note that display_size, precision, scale and null_ok
+ # are not implemented.
cursor.rowcount # number of rows available in the result set
# Available after a call to execute.
@@ -71,6 +72,7 @@
from time import localtime
from decimal import Decimal
from math import isnan, isinf
+from collections import namedtuple
try:
long
@@ -196,8 +198,7 @@
res = self._src.fetch(1)[0]
# The column name is omitted from the return value.
# It will have to be prepended by the caller.
- res = (res[0], None, int(res[1]),
- None, None, None)
+ res = (res[0], None, int(res[1]), None, None, None)
self[oid] = res
return res
@@ -364,8 +365,8 @@
self.rowcount = self._src.ntuples
getdescr = self._type_cache.getdescr
coltypes = self._src.listinfo()
- self.description = [
- typ[1:2] + getdescr(typ[2]) for typ in coltypes]
+ self.description = [CursorDescription(
+ typ[1], *getdescr(typ[2])) for typ in coltypes]
self.lastrowid = None
else:
self.rowcount = totrows
@@ -439,6 +440,11 @@
pass # unsupported, but silently passed
+CursorDescription = namedtuple('CursorDescription',
+ ['name', 'type_code', 'display_size', 'internal_size',
+ 'precision', 'scale', 'null_ok'])
+
+
### Connection Objects
class Connection(object):
Modified: trunk/module/tests/test_dbapi20.py
==============================================================================
--- trunk/module/tests/test_dbapi20.py Wed Dec 30 16:56:42 2015 (r680)
+++ trunk/module/tests/test_dbapi20.py Wed Dec 30 17:39:53 2015 (r681)
@@ -75,6 +75,24 @@
self.assertTrue(ret is cur, 'execute() should return cursor')
self.assertEqual(cur.fetchone(), {'a': 1, 'b': 2})
+ def test_description_named(self):
+ con = self._connect()
+ cur = con.cursor()
+ cur.execute("select 123456789::int8 as col")
+ desc = cur.description
+ self.assertIsInstance(desc, list)
+ self.assertEqual(len(desc), 1)
+ desc = desc[0]
+ self.assertIsInstance(desc, tuple)
+ self.assertEqual(desc.name, 'col')
+ self.assertEqual(desc.type_code, 'int8')
+ self.assertIsNone(desc.display_size)
+ self.assertIsInstance(desc.internal_size, int)
+ self.assertEqual(desc.internal_size, 8)
+ self.assertIsNone(desc.precision)
+ self.assertIsNone(desc.scale)
+ self.assertIsNone(desc.null_ok)
+
def test_cursor_iteration(self):
con = self._connect()
cur = con.cursor()
_______________________________________________
PyGreSQL mailing list
[email protected]
https://mail.vex.net/mailman/listinfo.cgi/pygresql