python - PostgreSQL:plpython3u 中具有单值的集合返回函数

标签 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 数字列表,要么迭代具有单个值的元组或单个值值(value)观:

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 参数的函数;相反,输出类型必须始终定义为表(或通过类似方式)

有人可以纠正我吗?如果这是真的,那就太烦人了。我肯定在某个地方犯了错误吗?

最佳答案

你应该只返回一组整数:

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)    

根据 the documentation (强调):

The key point here is that you must write RETURNS SETOF record to indicate that the function returns multiple rows instead of just one. If there is only one output parameter, write that parameter's type instead of record.

关于python - PostgreSQL:plpython3u 中具有单值的集合返回函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47207389/

相关文章:

python - 元组 (a,b)=(b,a) 中的成员交换如何在内部工作?

Python:专注于 ttk.Notebook 选项卡

sql - 按案例排序,NULL 不是第一个也不是最后一个

postgresql - Postgres 中的 Unicode 规范化

python - PL/Python错误 "could not convert SPI error to Python exception"

postgresql - plpython,plpythonu,plpython2u有什么区别

python - 如何在 GDAL Python 中获得带状数组的正确比例?

mysql - SQL 挑战 - 显示具有特定列值的 N(1、X 或全部)行

sql - 合并具有相同列名的两个表,添加计数器

python - Pandas read_csv() 对我不起作用