PL / Python3-连接PLyResults

时间:2019-06-26 13:20:37

标签: python-3.x postgresql plpython

我想知道是否可以在函数内部以某种方式连接PLyResults。例如,假设首先我有一个函数_get_data,给定一个元组(id,索引)返回值表:

CREATE OR REPLACE FUNCTION _get_data(id bigint, index bigint):
RETURNS TABLE(oid bigint, id bigint, val double precision) AS
$BODY$

#...process for fetching the data, irrelevant for the question.
return recs    

$BODY$
LANGUAGE plpython3u;

现在,我希望能够创建一个这样定义的通用函数,该函数可为给定ID提取两个边界之间的数据,并使用先前的函数单独获取数据,然后以某种方式汇总结果:

CREATE OR REPLACE FUNCTION get_data(id bigint, lbound bigint, ubound bigint)
RETURNS TABLE(oid bigint, id bigint, val double precision) AS
$BODY$

concatenated_recs = [] #<-- For the sake of argument.
plan = plpy.prepare("SELECT oid, id, val FROM _get_data($1, $2);", ['bigint', 'bigint'])
for i in range(lbound, ubound+1):
    recs = plpy.execute(plan, [id, i]) # <-- Records fetched individually 
    concatenated_recs += [recs] #<-- Not sure how to concatenate them...

return concatenated_recs

$BODY$
LANGUAGE plpython3u; 

2 个答案:

答案 0 :(得分:0)

尽管我无法找到一种方法来合并PL / Python文档中的结果,但是从06-2019开始,我不确定该语言是否支持此资源,我可以通过创建一个临时表,为每次迭代在其中插入记录,然后返回完整表:

CREATE OR REPLACE FUNCTION get_data(id bigint, lbound bigint, ubound bigint)
RETURNS TABLE(oid bigint, id bigint, val double precision) AS
$BODY$

#Creates the temp table
plpy.execute("""CREATE TEMP TABLE temp_results(oid bigint, id bigint, val double precision)
ON COMMIT DROP""")

plan = plpy.prepare("INSERT INTO temp_results SELECT oid, id, val FROM _get_data($1, $2);", 
['bigint', 'bigint'])

#Inserts the results in the temp table
for i in range(lbound, ubound+1):
    plpy.execute(plan, [id, i])

#Returns the whole table
recs = plpy.execute("SELECT * FROM temp_results")
return recs

$BODY$
LANGUAGE plpython3u; 

答案 1 :(得分:0)

也许我遗漏了一些东西,但是您给出的答案看起来像是此查询的一个较慢,更复杂的版本:

SELECT oid, id, val 
FROM generate_series(your_lower_bound, your_upper_bound) AS g(i),
_get_data(your_id, i);

您可以将其放在没有循环或临时表的简单SQL函数中:

CREATE OR REPLACE FUNCTION get_data(id bigint, lbound bigint, ubound bigint)
RETURNS TABLE(oid bigint, id bigint, val double precision) AS
$BODY$
SELECT oid, id, val 
FROM generate_series(lbound, ubound) AS g(i),
_get_data(id, i);
$BODY$ LANGUAGE SQL;