PL/Python & postgreSQL:return 一个 table 多列的最佳方法是什么?
PL/Python & postgreSQL: What is the best way to return a table of many columns?
在Pl/Python "RETURNS setof" 或"RETURNS table" 子句中用于return 类table 结构化数据。在我看来,必须提供每一列的名称才能获得 table returned。如果你有一个包含几列的 table ,这是一件容易的事。但是,如果您有一个包含 200 列的 table,最好的方法是什么?我必须输入所有列的名称(如下所示)还是有办法解决它?任何帮助将非常感激。
下面是一个使用 "RETURNS table" 子句的例子。代码片段在 postgres 中创建一个 table (mysales),填充它,然后使用 Pl/Python 获取它并 returning 列值。为简单起见,我只 returning 来自 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"
试试这个:
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';
其中 return 个:
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)
像 Greenplum 和 HAWQ 这样的 MPP 需要考虑的事情是争取将数据作为参数并 return 作为结果的函数,而不是在函数本身中生成数据。相同的代码在每个段上执行,因此偶尔会出现意想不到的副作用。
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';
请注意,要使用原始示例中的相同数据,我必须将每一列别名为 myType
中的相应名称。此外,如果走这条路,您将必须枚举 mysales
的所有列 - 尽管您可以使用它来减轻一些手册,但没有直接的方法 CREATE TYPE foo LIKE tableBar
枚举所有 names/types:
的工作
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 ;
其中 return 个:
columns
-------------------------------------------------------------------
id integer, year integer, qtr integer, day integer, region text,
(1 row)
在Pl/Python "RETURNS setof" 或"RETURNS table" 子句中用于return 类table 结构化数据。在我看来,必须提供每一列的名称才能获得 table returned。如果你有一个包含几列的 table ,这是一件容易的事。但是,如果您有一个包含 200 列的 table,最好的方法是什么?我必须输入所有列的名称(如下所示)还是有办法解决它?任何帮助将非常感激。
下面是一个使用 "RETURNS table" 子句的例子。代码片段在 postgres 中创建一个 table (mysales),填充它,然后使用 Pl/Python 获取它并 returning 列值。为简单起见,我只 returning 来自 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"
试试这个:
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';
其中 return 个:
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)
像 Greenplum 和 HAWQ 这样的 MPP 需要考虑的事情是争取将数据作为参数并 return 作为结果的函数,而不是在函数本身中生成数据。相同的代码在每个段上执行,因此偶尔会出现意想不到的副作用。
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';
请注意,要使用原始示例中的相同数据,我必须将每一列别名为 myType
中的相应名称。此外,如果走这条路,您将必须枚举 mysales
的所有列 - 尽管您可以使用它来减轻一些手册,但没有直接的方法 CREATE TYPE foo LIKE tableBar
枚举所有 names/types:
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 ;
其中 return 个:
columns
-------------------------------------------------------------------
id integer, year integer, qtr integer, day integer, region text,
(1 row)