2015-05-28 13 views
6

Ich versuche, einen serverseitigen Cursor in psycop2 zu verwenden, wie in this blog post beschrieben. Im Wesentlichen wird dies erreicht mitWie kann ich serverseitige Cursor mit Django und Psycopg2 verwenden?

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') 

Wenn ich die Abfrage ausführen:

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

ich ein ProgrammingError:

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

Ich habe ganz naiv versucht, eine erstellen Transaktion mit

cursor.execute('BEGIN') 

vor der Ausführung der SELECT Anweisung. Dies führt jedoch zu demselben Fehler, der von der Zeile cursor.execute('BEGIN') generiert wird.

Ich habe auch versucht

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

verwenden, aber ich die gleichen Ergebnisse erhalten.

Wie mache ich eine Transaktion in Django?

+0

Aus der Fehlermeldung scheint es, dass sich der Cursor außerhalb von Transaktionen befindet . Versuchen Sie, Cursor innerhalb von Transaktionen zu verwenden. –

Antwort

-1

Versuchen Sie folgendes:

from django.db import transaction 

# prepare your cursor here ... 

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

Auch zu diesem Thema einen Blick auf offizielle Dokumente nehmen: https://docs.djangoproject.com/en/1.8/topics/db/transactions/

+0

Dies erstellt keinen serverseitigen Cursor. –

+0

WARNUNG: DIES ENTHÄLT EINE SQL-INJEKTION. Außerdem erstellt es keinen SERVER-Seitencursor. – Blubber

0

Cursor sollten innerhalb von Transaktionen verwendet werden. Sie müssen eine Transaktion definieren und den Cursor darin verwenden.

- müssen in einer Transaktion sein, Cursor zu verwenden.

Aufgenommen von here.

3

Wie Sie in Ihrer Frage erwähnen, aber ich werde hier für zukünftige Leser wiederholen: es ist auch möglich, Verwenden Sie explizit benannte Cursor, ohne Djangos öffentliche API zu umgehen:

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) 
Verwandte Themen