如何在django和psycopg2中使用服务器端游标?

时间:2015-05-28 15:15:13

标签: django postgresql transactions psycopg2

我正在尝试在psycop2中使用服务器端光标,详见this blog post。从本质上讲,这是通过

实现的
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')

执行查询时:

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

我得到ProgrammingError

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

我天真地尝试使用

创建交易
cursor.execute('BEGIN')

在执行SELECT语句之前。但是,这会导致cursor.execute('BEGIN')行生成相同的错误。

我也尝试过使用

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

但我得到的结果相同。

如何在django中进行交易?

3 个答案:

答案 0 :(得分:5)

正如你在问题中提到的那样,我将在此重申未来的读者:也可以使用明确命名的游标而不绕过Django的公共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)

答案 1 :(得分:0)

游标内部应使用游标。您需要定义一个事务并在其中使用游标。

  

- 需要在事务中使用游标。

取自here

答案 2 :(得分:-5)

试试这个:

from django.db import transaction

# prepare your cursor here ...

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

另请参阅有关此主题的官方文档: https://docs.djangoproject.com/en/1.8/topics/db/transactions/