Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I use server-side cursors with django and psycopg2?

I'm trying to use a server-side curser in psycop2 as detailed in this blog post. In essence, this is achieved with

from django.db import connection

if connection.connection is None:
    cursor = connection.cursor()
    # This is required to populate the connection object properly

cursor = connection.connection.cursor(name='gigantic_cursor')

When I execute the query:

cursor.execute('SELECT * FROM %s WHERE foreign_id=%s' % (table_name, id))

I get a ProgrammingError:

psycopg2.ProgrammingError: can't use a named cursor outside of transactions

I've naively tried to create a transaction using

cursor.execute('BEGIN')

before executing the SELECT statement. However, that results in the same error generated from the cursor.execute('BEGIN') line.

I've also tried using

cursor.execute('OPEN gigantic_cursor FOR SELECT * FROM %s WHERE foreign_id=%s' % (table_name, id))

but I get the same results.

How do I make a transaction in django?

like image 276
drs Avatar asked May 28 '15 15:05

drs


1 Answers

As you mention in your question but I'll reiterate here for future readers: it's also possible to use explicitly named cursors without bypassing Django's public API:

from django.db import connection, transaction

with transaction.atomic(), connection.cursor() as cur:
    cur.execute("""
        DECLARE mycursor CURSOR FOR
        SELECT *
        FROM giant_table
    """)
    while True:
        cur.execute("FETCH 1000 FROM mycursor")
        chunk = cur.fetchall()
        if not chunk:
            break
        for row in chunk:
            process_row(row)
like image 93
David Wolever Avatar answered Oct 23 '22 01:10

David Wolever