cursor
s support the with
usage pattern, which will automatically close them once the block has completed. That can be a very useful pattern for when you are doing compact operations with the cursors.
At other times, cursors may need to be used throughout a function, or multiple cursors may need to be used, and so in that case the with
pattern would make less sense, and it would be best declared at function-level scope.
Also keep in mind the importance of named cursors
, which is where psycopg cursors and Postgres cursors intertwine. Simply by giving the name
attribute a value in the constructor call, you will get a server-side cursor automatically which can then be iterated over just as any Python collection would, and which performs chunked fetches.
The chunk size can be altered, although it fetches in blocks of 2000 by default. This is particularly important when querying large tables, as you can quickly run out of memory client side with a huge result set. psycopg abstracts having to deal with Postgres cursors directly, and the next chunk is fetched transparently during the iteration of the cursor when needed.
Keep in mind that a named cursor can really only be used for one thing -- a query that you then iterate over; if you try to execute another query on the same cursor it will, if memory serves, throw an exception. With non-named cursors you can re-use the same cursor across executes once you're done with the results.
I generally use named cursors for any queries that I think might even have a chance of returning a fairly large result set, and non-named cursors for small queries and other commands such as updates, deletes, table creates, etc.