pg8000 и cursor.fetchall() не могут вернуть записи, если число записей умеренное
Я пользуюсь адаптером pg8000
читать в записи в моей БД со следующим кодом:
cursor = conn.cursor()
results = cursor.execute("SELECT * from data_" + country + " WHERE date >= %s AND date <= %s AND time >= %s AND time <= %s", (datetime.date(fromdate[0], fromdate[1], fromdate[2]), datetime.date(todate[0], todate[1], todate[2]),datetime.time(fromtime[0],fromtime[1]), datetime.time(totime[0],totime[1])))
results = cursor.fetchall()
Проблема возникает, когда я выбираю диапазон дат, в который входит, скажем, 100 записей. Количество записей невелико, но этого достаточно, чтобы вызвать следующую проблему, и я не могу понять, откуда эта проблема может возникнуть - так как она, похоже, зависит от количества записей, возвращаемых обратно. Например: results = cursor.fetchall()
кажется, работает просто отлично и возвращает один результат.
Я получаю сообщение об ошибке:
File "/mnt/opt/Centos5.8/python-2.7.8/lib/python2.7/site-packages/pg8000/core.py", line 1650, in handle_messages
raise error
pg8000.errors.ProgrammingError: ('ERROR', '34000', 'portal "pg8000_portal_0" does not exist')
Очевидно, я не могу найти способ исправить это, несмотря на исследование.
Когда используешь fetchmany()
Вот результаты:
results = cursor.fetchmany(100)
РАБОТЫ - ограничено до 100
results = cursor.fetchmany(101)
FAILS - та же ошибка, что и выше
2 ответа
В режиме автоматической фиксации вы не можете получить больше строк, чем хранится в кэше pg8000 (по умолчанию 100).
Я сделал коммит, который дает лучшее сообщение об ошибке, когда это произойдет, что будет в следующей версии pg8000.
Причина в том, что если число строк, возвращаемых запросом, больше, чем количество строк в кэше pg8000, портал базы данных остается открытым, а затем, когда кэш-память пуста, из портала выбирается больше строк. Портал может существовать только внутри транзакции, поэтому в режиме автоматической фиксации портал сразу же закрывается после извлечения первой партии строк. Если вы попытаетесь получить вторую партию с портала, вы получите сообщение об ошибке "портал не существует", о котором сообщалось в вопросе.
Похоже, это можно решить, установив:
conn.autocommit = False
Теперь код выглядит так:
conn.autocommit = False
cursor = conn.cursor()
results = cursor.execute("SELECT * from data_" + country + " WHERE date >= %s AND date <= %s AND time >= %s AND time <= %s", (datetime.date(fromdate[0], fromdate[1], fromdate[2]), datetime.date(todate[0], todate[1], todate[2]),datetime.time(fromtime[0],fromtime[1]), datetime.time(totime[0],totime[1])))
results = cursor.fetchall()
Я не уверен, почему это так, но кажется, что число записей 100 ограничено, если для параметра autocommit установлено значение True