PostgreSQL:在plpython3u中使用单值设置返回函数

时间:2017-11-09 16:49:21

标签: python postgresql plpython

我想在PostgreSQL中编写一个返回一组文本的plpython3u函数。我偶然发现了一个看起来很奇怪的难题。根据手册,我可以执行以下操作:

drop schema if exists X cascade;
create schema X;

create type X.greeting AS (
  who text
  );

create function X.greet( how text )
  returns setof X.greeting language plpython3u as $$
  for who in [ 'World', 'PostgreSQL', 'PL/Python' ]:
    yield ( who, )
  $$;

这是一个Python函数,它返回一组包含单个文本的行;这么多工作,我确实得到了预期的输出:

select X.greet( 'helo' );

    greet     
--------------
 (World)
 (PostgreSQL)
 (PL/Python)
(3 rows)

select * from X.greet( 'helo' );

    who     
------------
 World
 PostgreSQL
 PL/Python
(3 rows)

到目前为止一切顺利。但是,我不想为此目的编写表定义,我想使用setof record代替,就像在这个例子中(碰巧使用整数,但仍然):

create function X.pairs_of_integers_A( out integer, out integer )
  returns setof record language plpython3u as $$
  return [ ( 12, 24, ), ( 36, 48, ), ( 60, 72, ) ]
  $$;

create function X.pairs_of_integers_B( out integer, out integer )
  returns setof record language plpython3u as $$
  for pair in [ ( 12, 24, ), ( 36, 48, ), ( 60, 72, ) ]:
    yield pair
  $$;

select * from X.pairs_of_integers_A();
select * from X.pairs_of_integers_B();

 column1 | column2 
---------+---------
      12 |      24
      36 |      48
      60 |      72
(3 rows)

 column1 | column2 
---------+---------
      12 |      24
      36 |      48
      60 |      72
(3 rows)

现在我们来到有趣的部分。从上面概括,下面的一个或多个公式应该是正确的:返回一组单个值,返回Python元组列表,Python数列表,或者使用单个值或单个值迭代元组值:

create function X.single_integers_A( out integer )
  returns setof record language plpython3u as $$
  return [ ( 12, ), ( 36, ), ( 60, ), ]
  $$;

create function X.single_integers_B( out integer )
  returns setof record language plpython3u as $$
  return [ 12, 36, 60, ]
  $$;

create function X.single_integers_C( out integer )
  returns setof record language plpython3u as $$
  for n in [ ( 12, ), ( 36, ), ( 60, ), ]
    yield n
  $$;

create function X.single_integers_D( out integer )
  returns setof record language plpython3u as $$
  for n in [ 12, 36, 60, ]
    yield n
  $$;

结果以上都不编译,它们都会导致SQL解析器抛出函数结果类型必须是整数,因为OUT参数。由于我的SQL解析器没有查看Python函数,这让我怀疑 -

在PostgreSQL中,无法使用returns setof record和单个out参数定义函数;相反,输出类型必须始终定义为表格(或通过类似方式)

任何人都可以纠正我吗?如果这应该是真的那将是非常烦人的。当然我在某个地方犯了错误?

1 个答案:

答案 0 :(得分:1)

你应该只返回一组整数:

create or replace function x.single_integers()
returns setof integer language plpython3u as $$
    return [ 12, 36, 60 ]
$$;

select * from x.single_integers();

 single_integers 
-----------------
              12
              36
              60
(3 rows)    

Per the documentation(强调补充):

  

这里的关键点是你必须编写RETURNS SETOF记录来指示该函数返回多行而不是一行。 如果只有一个输出参数,请写入该参数的类型而不是记录。

相关问题