【问题标题】:Django + PostgreSQL Connection - Cannot use server side cursorDjango + PostgreSQL 连接 - 无法使用服务器端游标
【发布时间】:2019-03-03 09:40:25
【问题描述】:

我在 PostgreSQL 中有一个存储过程,它返回一个 refcursor(它的名称可以作为参数传递):

-- Example stored procedure....
CREATE OR REPLACE FUNCTION example_stored_procedure(ref refcursor, gid_number integer) RETURNS refcursor AS $$
DECLARE
ref refcursor;
BEGIN
 OPEN $1 for SELECT * FROM lucca_routes where gid = gid_number;
 RETURN $1;
END;
$$ LANGUAGE plpgsql;

然后,我可以通过这种方式从 postgres 控制台毫无问题地获取结果集:

BEGIN;
select example_stored_procedure('customcursor', 1);
FETCH ALL IN "customcursor";
COMMIT;

但是,我需要从 Django 应用程序中获取结果集(使用其 postgreSQL 连接)。根据this,我试过了:

from django.db import connections
from rest_framework.response import Response
from rest_framework.decorators import api_view

@api_view(['GET'])
def testing_procedure(request):
    connection = connections['default']
    with connection.cursor() as cursor:
        cursor.execute("BEGIN")
        cursor.callproc("example_stored_procedure", ['customcursor', 1])
        # "steal" the cursor - ERROR HERE!
        cursor2 = connection.cursor('customcursor')
        # fetch here the data from cursor2...
        return Response(result)

当我尝试“窃取”由 callproc() 返回的新游标(创建cursor2)时,出现错误:

TypeError: cursor() 接受 1 个位置参数,但给出了 2 个

我做错了什么?如何从 callproc() 返回的 refcursor 中获取数据?

我正在使用 psycopg2 2.7.5

【问题讨论】:

  • 您可以尝试create_cursor() 方法(new in Django 1.11),它有一个名称参数。 this question 的答案可能也会有所帮助。
  • 优秀@Alasdair。使用 create_cursor() 我可以使用并从服务器端游标获取数据。
  • 很高兴它成功了!如果您将解决方案添加为答案,以帮助未来的读者,那就太好了。

标签: django python-3.x postgresql


【解决方案1】:

我根据@Alasdair 的评论为未来的读者发布解决方案。

您可以使用 DatabaseWrapper 对象中的函数 create_cursor(self, name=None) 来使用服务器端游标。

在我的例子中:

def testing_procedure(request):
    connection = connections['default']
    with connection.cursor() as cursor:
        cursor.execute("BEGIN")
        cursor.callproc("example_stored_procedure", ['customcursor', 1])
        cursor2 = connection.create_cursor('customcursor')
        # fetch here the data from cursor2...
        result = cursor2.fetchall() # works!
        return Response(result)

【讨论】:

猜你喜欢
  • 2021-02-27
  • 2016-04-21
  • 2018-04-19
  • 1970-01-01
  • 2020-01-24
  • 1970-01-01
  • 2019-10-08
  • 2017-08-02
  • 2017-03-03
相关资源
最近更新 更多