Вы можете выполнить один запрос и разбить результаты на два списка:
with psycopg2.connect("dbname=test user=postgres") as conn:
with conn.cursor() as cur:
cur.execute("SELECT a, b, c, d FROM my_table WHERE a > 5 and (d < 10 or d > 20);")
rows = cur.fetchall()
r1 = [(i[0], i[1], i[2]) for i in rows if i[3] < 10]
r2 = [(i[0], i[1], i[2]) for i in rows if i[3] > 20]
Приведенное выше решение должно быть наиболее эффективным в тех случаях, когда набор результатов невелик. Кроме того, вы можете создать временную таблицу:
with psycopg2.connect("dbname=test user=postgres") as conn:
with conn.cursor() as cur:
cur.execute("""
CREATE TEMP TABLE t AS
SELECT a, b, c, d
FROM my_table
WHERE a > 5 and (d < 10 or d > 20);""")
cur.execute("SELECT a, b, c FROM t WHERE d < 10;")
r1 = cur.fetchall()
cur.execute("SELECT a, b, c FROM t WHERE d > 20;")
r2 = cur.fetchall()
Временная таблица будет автоматически удалена при закрытии соединения.
Если результирующий набор слишком велик, чтобы быть практически обработанным на клиентеside, используйте курсор на стороне сервера. Когда вы извлекаете отдельные строки в цикле, строки фактически извлекаются с сервера в сегментах. Вы можете определить размер ковшей, установив itersize
. .
r1 = []
r2 = []
with psycopg2.connect("dbname=test user=postgres") as conn:
with conn.cursor('my_cursor') as cur:
cur.itersize = 1000
cur.execute("SELECT a, b, c, d FROM my_table WHERE a < 5 and (d < 10 or d > 20);")
for row in cur:
if row[3] < 10:
r1.append((row[0], row[1], row[2]))
else:
r2.append((row[0], row[1], row[2]))