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

Reply via email to