2016-07-11 5 views
0

In Pl/Python「RETURNS setof」または「RETURNS table」節は、構造化データのような表を返すために使用されます。テーブルを返すためには、各列の名前を指定する必要があります。あなたがいくつかの列を持つテーブルを持っているなら、それは簡単なことです。しかし、200列のテーブルがある場合は、それを行うための最善の方法は何ですか?すべての列の名前を入力する必要がありますか(下図参照)、それを回避する方法がありますか?どんな助けでも大歓迎です。PL/PythonとpostgreSQL:多くのカラムのテーブルを返す最良の方法は何ですか?

以下は、「RETURNSテーブル」句を使用する例です。コードスニペットは、ポストグルにテーブル(mysales)を作成し、ポピュレートしてからPl/Pythonを使ってフェッチし、カラム値を返します。簡単にするために、私はテーブルから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" 
+0

'DISTRIBUTED BY'のみGreenplumはある:返し

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 ; 

。 –

+0

正しい。ありがとうございました。 – userDataScience

答えて

1

これを試してみてください:返す

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'; 

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のために考慮すべきデータを取る機能のために努力しています引数として返り、結果を返します。関数そのもののデータを視覚化する。すべてのセグメントで同じコードが実行されるため、意図しない副作用が生じることがあります。 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'; 

注、IはmyTypeで名前を対応する各列に別名しなければなりませんでした。また、mysalesのすべての列を列挙しなければなりません。CREATE TYPE foo LIKE tableBarへの直接的な方法はありませんが、これを使用してすべての名前/タイプを列挙する手作業の一部を緩和することができます:

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

マジックのように動作します!ありがとう、カイル!私はそのトリックが「返品」条項でなければならないことを知っていました。完全性のために、私の2番目の質問があります:この問題は 'returns setof'を使って解決できますか? – userDataScience

+0

"setof"を含むスニペットを次に示します。DROP TYPE IF EXISTS myType CASCADE; CREATE TYPE myType AS(id整数、x整数、y整数、sテキスト); myFunc()戻り値SETTY myType AS $$戻り値[範囲(0、d)]のiの場合は[rv [i]] $$ .... – userDataScience

+0

私は何を達成する方法を含めるかを更新しました。あなたが頼んでいると思う。いずれかまたは両方のソリューションが好きな場合は、その質問に回答としてマークしてください。 :-) –

関連する問題