I have read the documentation and several articles and posts and threads and all but I am not sure if I understand this clearly. Lets suppose this scenario:
1. I have a server side cursor.
2. I set the itersize to 1000.
3. I execute a SELECT query which would normally return 10000 records.
4. I use fetchmany to fetch 100 records at a time.
My question is how is this done behind the scene? My understanding is that the query is executed, but 1000 of the records are read by the server side cursor. The cursor refrains from reading the next 1000 unless it scrolls past the last record of the currently read 1000. Furthermore, the server side cursor holds the 1000 in the server's memory and scrolls over them 100 at a time, sending them to the client. I'm also curious to know what would the ram consumption look like? By my understanding, if executing the full query takes 10000 kb of the memory, the server side cursor would consume only 1000 kb on the server because it reads only 1000 records at a time and the client side cursor would use 100 kb. Is my understanding correct?
UPDATE Per the documents and the discussion we had in the responses, I would expect this code to print a list of 10 items at a time:
from psycopg2 import connect, extras as psg_extras
with connect(host="db_url", port="db_port", dbname="db_name", user="db_user", password="db_password") as db_connection:
with db_connection.cursor(name="data_operator",
cursor_factory=psg_extras.DictCursor) as db_cursor:
db_cursor.itersize = 10
db_cursor.execute("SELECT rec_pos FROM schm.test_data;")
for i in db_cursor:
print(i)
print(">>>>>>>>>>>>>>>>>>>")
However, in each iteration it prints just one record. The only way I get 10 records is if I use fetchmany:
from psycopg2 import connect, extras as psg_extras
with connect(host="db_url", port="db_port", dbname="db_name", user="db_user", password="db_password") as db_connection:
with db_connection.cursor(name="data_operator",
cursor_factory=psg_extras.DictCursor) as db_cursor:
db_cursor.execute("SELECT rec_pos FROM schm.test_data;")
records = db_cursor.fetchmany(10)
while len(records) > 0:
print(i)
print(">>>>>>>>>>>>>>>>>>>")
records = db_cursor.fetchmany(10)
Based on these two code snippets, what I'm guessing is happening in the scenario mentioned before is that given the code bellow...
from psycopg2 import connect, extras as psg_extras
with connect(host="db_url", port="db_port", dbname="db_name", user="db_user", password="db_password") as db_connection:
with db_connection.cursor(name="data_operator",
cursor_factory=psg_extras.DictCursor) as db_cursor:
db_cursor.itersize = 1000
db_cursor.execute("SELECT rec_pos FROM schm.test_data;")
records = db_cursor.fetchmany(100)
while len(records) > 0:
print(i)
print(">>>>>>>>>>>>>>>>>>>")
records = db_cursor.fetchmany(100)
... itersize is a server side thing. What it does is that when the query runs, it sets a limit to load only 1000 records from the database. But fetchmany is a client side thing. It gets 100 of the 1000 from the server. Each time fetchmany runs, the next 100 is fetched from the server. When all the 1000 on the server side are scrolled over, the next 1000 are fetched from the DB on the server side. But I'm rather confused because that does not seem to be what the docs imply. But then again... the code seems to imply that.