【问题标题】:How can I use server-side cursors with django and psycopg2?如何在 django 和 psycopg2 中使用服务器端游标?
【发布时间】:2015-08-11 04:47:12
【问题描述】:

我正在尝试在 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 中进行交易?

【问题讨论】:

  • 从错误消息看来,您的光标在事务之外。尝试在事务中使用游标。
  • 请参阅this answer,了解如何设置它的示例。

标签: django postgresql transactions psycopg2


【解决方案1】:

正如您在问题中提到的,但我会在这里为未来的读者重申:也可以在不绕过 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)

【讨论】:

    【解决方案2】:

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

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

    取自here

    【讨论】:

      猜你喜欢
      • 2017-05-17
      • 1970-01-01
      • 1970-01-01
      • 2019-03-03
      • 1970-01-01
      • 2015-06-20
      • 1970-01-01
      • 2016-02-15
      • 2018-04-19
      相关资源
      最近更新 更多