[PATCH] DictCursors with named DB cursors - updated for 2.0.9

Menno Smits <menno-jZ/TYErj1jVWk0Htik3J/[email protected]>
Newsgroups gmane.comp.python.db.psycopg.devel
Message-ID <[email protected]>
Hi Federico,

Attached is an updated version of the patch I sent a while back to fix
the problem I found when DictCursors are used with named DB cursors.
This version applies cleanly against psycopg 2.0.9.

Do you have plans to make another psycopg release soon? We're about to
start using psycopg where I work and we require this fix. It would be
nice not have to maintain the patch outside of the psycopg tree.

Regards,
Menno

_______________________________________________
Psycopg mailing list
Psycopg-IAPFreCvJWPBWskQ1e/[email protected]
http://lists.initd.org/mailman/listinfo/psycopg
dictcursor_with_named_cursor-2.0.9.patch (text/x-patch, 3.5 KB)
diff -Naur psycopg2-2.0.9-orig/lib/extras.py psycopg2-2.0.9-patched/lib/extras.py
--- psycopg2-2.0.9-orig/lib/extras.py	2009-02-23 20:38:30.000000000 +0000
+++ psycopg2-2.0.9-patched/lib/extras.py	2009-04-01 15:20:48.969884881 +0100
@@ -46,26 +46,29 @@
         self.row_factory = row_factory
 
     def fetchone(self):
+        res = _cursor.fetchone(self)
         if self._query_executed:
             self._build_index()
-        return _cursor.fetchone(self)
+        return res
 
     def fetchmany(self, size=None):
+        res = _cursor.fetchmany(self, size)
         if self._query_executed:
             self._build_index()
-        return _cursor.fetchmany(self, size)
+        return res
 
     def fetchall(self):
+        res = _cursor.fetchall(self)
         if self._query_executed:
             self._build_index()
-        return _cursor.fetchall(self)
+        return res
     
     def next(self):
-        if self._query_executed:
-            self._build_index()
         res = _cursor.fetchone(self)
         if res is None:
             raise StopIteration()
+        if self._query_executed:
+            self._build_index()
         return res
 
 class DictConnection(_connection):
@@ -74,7 +77,7 @@
         if name is None:
             return _connection.cursor(self, cursor_factory=DictCursor)
         else:
-	    return _connection.cursor(self, name, cursor_factory=DictCursor)
+            return _connection.cursor(self, name, cursor_factory=DictCursor)
 
 class DictCursor(DictCursorBase):
     """A cursor that keeps a list of column name -> index mappings."""
diff -Naur psycopg2-2.0.9-orig/tests/extras_dictcursor.py psycopg2-2.0.9-patched/tests/extras_dictcursor.py
--- psycopg2-2.0.9-orig/tests/extras_dictcursor.py	2008-05-05 16:41:37.000000000 +0100
+++ psycopg2-2.0.9-patched/tests/extras_dictcursor.py	2009-04-01 15:25:09.152792565 +0100
@@ -27,18 +27,41 @@
         self.conn = psycopg2.connect(tests.dsn)
         curs = self.conn.cursor()
         curs.execute("CREATE TEMPORARY TABLE ExtrasDictCursorTests (foo text)")
+        curs.execute("INSERT INTO ExtrasDictCursorTests VALUES ('bar')")
+        self.conn.commit()
 
     def tearDown(self):
         self.conn.close()
 
     def testDictCursor(self):
         curs = self.conn.cursor(cursor_factory=psycopg2.extras.DictCursor)
-        curs.execute("INSERT INTO ExtrasDictCursorTests VALUES ('bar')")
         curs.execute("SELECT * FROM ExtrasDictCursorTests")
         row = curs.fetchone()
         self.failUnless(row['foo'] == 'bar')
         self.failUnless(row[0] == 'bar')
 
+    def testDictCursorWithNamedCursorFetchOne(self):
+        self._testWithNamedCursor(lambda curs: curs.fetchone())
+
+    def testDictCursorWithNamedCursorFetchMany(self):
+        self._testWithNamedCursor(lambda curs: curs.fetchmany(100)[0])
+
+    def testDictCursorWithNamedCursorFetchAll(self):
+        self._testWithNamedCursor(lambda curs: curs.fetchall()[0])
+
+    def testDictCursorWithNamedCursorIter(self):
+        def rowUsingIter(curs):
+            for row in curs:
+                return row
+        self._testWithNamedCursor(rowUsingIter)
+
+    def _testWithNamedCursor(self, rowGetter):
+        curs = self.conn.cursor('somecursor', cursor_factory=psycopg2.extras.DictCursor)
+        curs.execute("SELECT * FROM ExtrasDictCursorTests")
+        row = rowGetter(curs)
+        self.failUnless(row['foo'] == 'bar')
+        self.failUnless(row[0] == 'bar')
+  
 
 def test_suite():
     return unittest.TestLoader().loadTestsFromName(__name__)
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.