简体   繁体   English

PL / Python和postgreSQL:返回包含多列的表的最佳方法是什么?

[英]PL/Python & postgreSQL: What is the best way to return a table of many columns?

In Pl/Python "RETURNS setof" or "RETURNS table" clause are used to return a table like structured data. 在Pl / Python中,“ RETURNS setof”或“ RETURNS table”子句用于返回类似于结构化数据的表。 It seems to me that one has to provide the name of each column to get a table returned. 在我看来,必须提供每一列的名称才能返回表。 If you have a table with a few columns it is an easy thing. 如果您的表有几列,这是一件容易的事。 However, if you have a table of 200 columns, what's the best way to do that? 但是,如果您有一个包含200列的表,那么执行此操作的最佳方法是什么? Do I have to type the names of all of columns (as shown below) or there is a way to get around it? 我是否必须键入所有列的名称(如下所示),还是有一种解决方法? Any help would be much appreciated. 任何帮助将非常感激。

Below is an example that uses "RETURNS table" clause. 下面是一个使用“ RETURNS table”子句的示例。 The code snippets creates a table (mysales) in postgres, populate it and then use Pl/Python to fetch it and returning the column values. 代码段在postgres中创建一个表(mysales),将其填充,然后使用Pl / Python来获取该表并返回列值。 For simplicity I am only returning 4 columns from the table. 为简单起见,我仅从表中返回4列。

DROP TABLE IF EXISTS mysales;

CREATE TABLE mysales (id int, year int, qtr int, day int, region
text)  DISTRIBUTED BY (id);

INSERT INTO mysales VALUES 
(1, 2014, 1,1, 'north america'),
(2, 2002, 2,2, 'europe'),
(3, 2014, 3,3, 'asia'),
(4, 2010, 4,4, 'north-america'),
(5, 2014, 1,5, 'europe'),
(6, 2009, 2,6, 'asia'),
(7, 2002, 3,7, 'south america');

DROP FUNCTION IF EXISTS myFunc02();
CREATE OR REPLACE FUNCTION myFunc02() 
RETURNS TABLE (id integer, x integer, y integer, s text) AS 
$$
rv = plpy.execute("SELECT * FROM mysales ORDER BY id", 5)
d  = rv.nrows()
return ( (rv[i]['id'],rv[i]['year'], rv[i]['qtr'], rv[i]['region'])
for i in range(0,d) ) 
$$ LANGUAGE 'plpythonu';

SELECT * FROM myFunc02();

#Here is the output of the SELECT statement:
1; 2014; 1;"north america" 
2; 2002; 2;"europe" 
3; 2014; 3;"asia" 
4; 2010; 4;"north-america" 
5; 2014; 1;"europe" 
6; 2009; 2;"asia" 
7; 2002; 3;"south america"

Try this: 尝试这个:

CREATE OR REPLACE FUNCTION myFunc02() 
RETURNS TABLE (like mysales) AS 
$$
rv = plpy.execute('SELECT * FROM mysales ORDER BY id;', 5)
d  = rv.nrows()
return rv[0:d]
$$ LANGUAGE 'plpythonu';

which returns: 返回:

gpadmin=# SELECT * FROM myFunc02();                             
 id | year | qtr | day |    region
----+------+-----+-----+---------------
  1 | 2014 |   1 |   1 | north america
  2 | 2002 |   2 |   2 | europe
  3 | 2014 |   3 |   3 | asia
  4 | 2010 |   4 |   4 | north-america
  5 | 2014 |   1 |   5 | europe
(5 rows)

Something to consider for MPP like Greenplum and HAWQ is to strive for functions that take data as an argument and return a result, rather than originating the data in the function itself. 对于MPP(例如Greenplum和HAWQ),需要考虑的事情是争取将数据作为参数并返回结果的函数,而不是在函数本身中发起数据。 The same code executes on every segment so occasionally there can be unintended side effects. 相同的代码在每个段上执行,因此偶尔会有意外的副作用。

Update for SETOF variant: SETOF变体的更新:

CREATE TYPE myType AS (id integer, x integer, y integer, s text);

CREATE OR REPLACE FUNCTION myFunc02a() 
RETURNS SETOF myType AS 
$$

# column names of myType ['id', 'x', 'y', 's']
rv = plpy.execute("SELECT id, year as x, qtr as y, region as s FROM mysales ORDER BY id", 5)
d  = rv.nrows()

return rv[0:d]
$$ LANGUAGE 'plpythonu';

Note, to use the same data from the original example, I had to alias each of the columns to corresponding names in myType . 注意,要使用原始示例中的相同数据,我必须将每列的别名都命名为myType相应名称。 Also, you'll have to enumerate all of the columns of mysales if going this route - there isn't a straightforward way to CREATE TYPE foo LIKE tableBar although you might be able to use this to alleviate some of the manual work of enumerate all the names/types: 此外,如果要使用此路线,则必须枚举mysales所有列-尽管可以使用此方法来减轻一些枚举全部的手动工作,但没有一种直接CREATE TYPE foo LIKE tableBar方法。名称/类型:

select string_agg(t.attname || ' ' || t.format_type || ', ') as columns  from 
(
SELECT a.attname,
  pg_catalog.format_type(a.atttypid, a.atttypmod),
  (SELECT substring(pg_catalog.pg_get_expr(d.adbin, d.adrelid) for 128)
   FROM pg_catalog.pg_attrdef d
   WHERE d.adrelid = a.attrelid AND d.adnum = a.attnum AND a.atthasdef),
  a.attnotnull, a.attnum,
  a.attstorage ,
  pg_catalog.col_description(a.attrelid, a.attnum)
FROM pg_catalog.pg_attribute a
LEFT OUTER JOIN pg_catalog.pg_attribute_encoding e
ON   e.attrelid = a .attrelid AND e.attnum = a.attnum
WHERE a.attrelid = (SELECT oid FROM pg_class WHERE relname = 'mysales') AND a.attnum > 0 AND NOT a.attisdropped
ORDER BY a.attnum
) t ;

which returns: 返回:

                              columns
-------------------------------------------------------------------
 id integer, year integer, qtr integer, day integer, region text,
(1 row)

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

相关问题 在 Python 中打印带有分隔符的表格的最佳方法是什么 - What is the best way to print a table with delimiters in Python 在pyspark中将许多小文件转换为Delta表的最佳方法是什么? - What is the best way to transform many small files to Delta table in pyspark? 在python Tornado服务器上处理许多路径的最佳方法是什么? - What's the best way to handle many paths on a python Tornado server? 用python显示交互式表格的最佳方式(用户可调整列) - Best way to show interactive table with python (columns adjustably by user) 建立热量的最佳方法 map 和具有多个原始/列的表 - python - the best way to build heat map & table with multiple raws/columns - python 在Python中访问数组列的最佳方法是什么? - What's the best way to access columns of an array in Python? 在 python 中执行 OneHotEncoder 后保留列名的最佳方法是什么? - what is the best way to keep columns names after doing OneHotEncoder in python? 使用python和xlrd,从电子表格中读取2列的最佳方法是什么 - Using python and xlrd, what is the best way to read 2 columns from a spreadsheet 将字符串返回到SWIG python接口的最佳方法是什么? - What is the best way to return a string to the SWIG python interface? 在 bash 脚本中从 Python 返回数组值的最佳方法是什么? - What is best way to return an array value form a Python in a bash script?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM