Don't fetch all the records iterating a NamedTuple cursor on a named cursor

This commit is contained in:
Daniele Varrazzo 2011-04-26 19:26:19 +01:00
parent ffa7a62b93
commit c61ec094a3
3 changed files with 27 additions and 2 deletions

1
NEWS
View File

@ -8,6 +8,7 @@ What's new in psycopg 2.4.1
- Correctly detect an empty query sent to the backend (ticket #46).
- Fixed a SystemError clobbering libpq errors raised without SQLSTATE.
Bug vivisectioned by Eric Snow.
- Fixed interaction between NamedTuple and server-side cursors.
- Allow to specify --static-libpq on setup.py command line instead of
just in 'setup.cfg'. Patch provided by Matthew Ryan (ticket #48).

View File

@ -304,7 +304,14 @@ class NamedTupleCursor(_cursor):
return [nt(*t) for t in ts]
def __iter__(self):
return iter(self.fetchall())
# Invoking _cursor.__iter__(self) goes to infinite recursion,
# so we do pagination by hand
while 1:
recs = self.fetchmany(self.itersize)
if not recs:
return
for rec in recs:
yield rec
try:
from collections import namedtuple

View File

@ -14,9 +14,11 @@
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
# License for more details.
import time
from datetime import timedelta
import psycopg2
import psycopg2.extras
from testutils import unittest, skip_if_no_namedtuple
from testutils import unittest, skip_before_postgres, skip_if_no_namedtuple
from testconfig import dsn
@ -293,6 +295,21 @@ class NamedTupleCursorTest(unittest.TestCase):
recs = curs.fetchall()
self.assertEqual(recs[0].i, 42)
@skip_if_no_namedtuple
@skip_before_postgres(8, 0)
def test_not_greedy(self):
curs = self.conn.cursor('tmp')
curs.itersize = 2
curs.execute("""select clock_timestamp() as ts from generate_series(1,3)""")
recs = []
for t in curs:
time.sleep(0.01)
recs.append(t)
# check that the dataset was not fetched in a single gulp
self.assert_(recs[1].ts - recs[0].ts < timedelta(seconds=0.005))
self.assert_(recs[2].ts - recs[1].ts > timedelta(seconds=0.0099))
def test_suite():
return unittest.TestLoader().loadTestsFromName(__name__)