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

Другие вопросы по тегам