cx_Oracle:Как перебрать набор результатов?
Вопрос
Существует несколько способов перебора набора результатов.Каков компромисс каждого из них?
Решение
Канонический способ — использовать встроенный итератор курсора.
curs.execute('select * from people')
for row in curs:
print row
Вы можете использовать fetchall()
чтобы получить все строки сразу.
for row in curs.fetchall():
print row
Это может быть удобно использовать для создания списка Python, содержащего возвращаемые значения:
curs.execute('select first_name from people')
names = [row[0] for row in curs.fetchall()]
Это может быть полезно для небольших наборов результатов, но может иметь плохие побочные эффекты, если набор результатов большой.
Вы должны ждать, пока весь набор результатов будет возвращен в ваш клиент -процесс.
Вы можете съесть много памяти в своем клиенте, чтобы удерживать встроенный список.
Для Python может потребоваться некоторое время, чтобы построить и деконструировать список, который вы собираетесь немедленно отказаться.
Если вы знаете, что в наборе результатов возвращается одна строка, вы можете вызвать fetchone()
чтобы получить одну строку.
curs.execute('select max(x) from t')
maxValue = curs.fetchone()[0]
Наконец, вы можете перебрать набор результатов в цикле, извлекая по одной строке за раз.В общем, в этом нет особого преимущества перед использованием итератора.
row = curs.fetchone()
while row:
print row
row = curs.fetchone()
Другие советы
Я предпочитаю использовать итератор курсора, но сначала устанавливаю свойство arraysize курсора.
curs.execute('select * from people')
curs.arraysize = 256
for row in curs:
print row
В этом примере cx_Oracle будет извлекать 256 строк из Oracle за раз, сокращая количество сетевых циклов, которые необходимо выполнить.
Есть также способ psyco-pg
кажется, делает это...Судя по тому, что я понял, похоже, что он создает словарные прокси-строки для сопоставления поиска ключа с блоком памяти, возвращаемым запросом.В этом случае получение всего ответа и работа с аналогичной прокси-фабрикой над строками кажется полезной идеей.Если подумать, это больше похоже на Lua, чем на Python.
Кроме того, это должно быть применимо ко всем PEP-249 DBAPI2.0 интерфейсы, а не только Oracle, или вы имели в виду просто самый быстрый с использованием Оракул?