Я использую pgdb (PyGreSQL) в своем проекте для подключения к работающей БД.
Я написал генератор для выборки строк с нумерацией страниц из огромных таблиц.
# DbHelper.py
...
def GetMultipleRowsGenerator(self, query, page_size=None):
"""Execute a query and return the generator
for a fetching rows
"""
if self._condition:
self._condition.acquire()
try:
self.VerifyConnection()
return pgsqlUtils.dbGetMultipleRowsGenerator(self._dbConnection, query, page_size)
finally:
if self._condition:
self._condition.release()
...
# pgsqlUtils.py
...
def dbGetMultipleRowsGenerator(db, query, page_size=None):
if not query.strip().lower().startswith('select '):
raise ValueError("Bad query '%s'. Query must starts with 'SELECT ...' for a generator." % query)
if page_size is not None:
try:
page_size = int(page_size)
except TypeError:
raise ValueError("Expected int type for 'page_size' (%s given)." % page_size)
if page_size <= 0:
raise ValueError("The 'page_size' must be greater than 0 (but %s given)." % page_size)
def get_generator(q):
c = None
try:
c = db.cursor()
except SyntaxError:
pass
try:
c.execute(q)
while True:
r = c.fetchone()
if r is None:
break
yield r
except SyntaxError:
pass
finally:
if c is not None:
c.close()
db.commit()
orig_query = query
page = -1
while True:
query = orig_query
if page_size is not None:
page += 1
offset = page * page_size
query = "%s OFFSET %s LIMIT %s" % (orig_query, offset, page_size)
generator = get_generator(query)
row = None
while True:
try:
row = next(generator)
except StopIteration:
break
yield row
if row is None:
break # no rows - end of table
...
с использованием генератора:
curr_data_generator = \
self.conn.GetMultipleRowsGenerator("SELECT * FROM %s" % temp_tablename, page_size=100000)
while True:
try:
data = next(curr_data_generator)
except StopIteration:
break
# do something with data ...
И это хорошо работает, но иногда я получаю следующее исключение:
File "pgsqlUtils.py", line 111, in dbGetMultipleRowsGenerator
File "pgsqlUtils.py", line 84, in get_generator
File "/usr/myproject/depot/Python-3.4.3/lib/python3.4/site-packages/PyGreSQL-5.0-py3.4-linux-x86_64.egg/pgdb.py", line 958, in fetchone
res = self.fetchmany(1, False)
File "/usr/myproject/depot/Python-3.4.3/lib/python3.4/site-packages/PyGreSQL-5.0-py3.4-linux-x86_64.egg/pgdb.py", line 981, in fetchmany
result = self._src.fetch(size)
pg.DatabaseError: Last query did not return tuples
Сведения об окружающей среде
- Python версия: 3.4.3
- ОС: CentOS релиз 6,6
- Я использую этот код в многопоточном режиме.
Почему это происходит? И как я могу это исправить?