简体   繁体   English

从 Python 的 Redshift 过程调用返回数据

[英]Return data from Python's Redshift procedure call

redshift_connector is defined to be aligned with https://peps.python.org/pep-0249/#id24 but I can't, after calling procedure, retrieve data into a dataframe. redshift_connector被定义为与https://peps.python.org/pep-0249/#id24对齐,但我无法在调用过程后将数据检索到 dataframe。

Instead I'm getting 'mycursor' value.相反,我得到的是'mycursor'值。 How to overcome this?如何克服这个?

fetch*() methods don't allow passing argument that will allow getting into data in mycursor . fetch*()方法不允许传递允许进入mycursor中的数据的参数。

I also tried RECORDS type but no luck.我也试过RECORDS类型但没有运气。

Procedure's body :程序的主体

--CREATE TABLE reporting.tbl(a int, b int);
--INSERT INTO reporting.tblVALUES(1, 4);

CREATE OR REPLACE PROCEDURE reporting.procedure(param IN integer, rs_out INOUT refcursor)
LANGUAGE plpgsql
AS $$

BEGIN
  OPEN rs_out FOR SELECT a FROM reporting.tbl;
END;
$$;

Python code : Python 代码

import redshift_connector

conn = redshift_connector.connect(
     host='xyz.xyz.region.redshift.amazonaws.com',
     database='db',
     port=5439,
     user="user",
     password='p@@s'
)
  

cursor = conn.cursor()

cursor.execute("BEGIN;") 
res = cursor.callproc("reporting.procedure", parameters=[1, 'mycursor'])
res = cursor.fetchall()
cursor.execute("COMMIT;")

#returns (['mycursor'],)
print(res)

I think you are trying to define 2 cursors and only one is allowed.我认为您正在尝试定义 2 个游标,但只允许一个。 "conn.cursor()" creates a cursor with name defined by redshift_connector. “conn.cursor()”创建一个 cursor,名称由 redshift_connector 定义。 "OPEN rs_out FOR SELECT a FROM reporting.tbl;" “打开 rs_out FOR SELECT a FROM reporting.tbl;” in your procedure opens a second cursor with the name mycursor.在您的程序中打开第二个 cursor,名称为 mycursor。 The "cursor.fetchall()" is trying to fetch from the first cursor (and possibly erroring). “cursor.fetchall()”试图从第一个 cursor 中获取(并且可能出错)。 No command is fetching from mycursor.没有从 mycursor 获取命令。

I don't believe there is a way to get "cursor.fetchall()" to point to a different cursor name so I think you need to run the SQL commands (CALL, FETCH, etc) directly.我认为没有办法让“cursor.fetchall()”指向不同的 cursor 名称,因此我认为您需要直接运行 SQL 命令(CALL、FETCH 等)。

Something like this:是这样的:

import redshift_connector

conn = redshift_connector.connect(
     host='xyz.xyz.region.redshift.amazonaws.com',
     database='db',
     port=5439,
     user="user",
     password='p@@s'
)

conn.run("BEGIN;") 
res = conn.run("CALL reporting.procedure(1, 'mycursor')")
res = conn.run("FETCH ALL FROM mycursor;")
conn.run("COMMIT;")

print(res)

Be aware that if you are on a single node Redshift cluster FETCH ALL isn't allowed and you will need to use FETCH FORWARD instead.请注意,如果您在单节点 Redshift 集群上,则不允许 FETCH ALL,您将需要改用 FETCH FORWARD。

Above untested and off the cuff.以上未经测试和即兴发挥。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM