PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

PL/Python &postgreSQL:Was ist der beste Weg, um eine Tabelle mit vielen Spalten zurückzugeben?

Versuchen Sie Folgendes:

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

was zurückgibt:

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)

Etwas, das für MPP wie Greenplum und HAWQ zu berücksichtigen ist, ist das Streben nach Funktionen, die Daten als Argumente verwenden und ein Ergebnis zurückgeben, anstatt die Daten in der Funktion selbst zu erzeugen. Derselbe Code wird auf jedem Segment ausgeführt, daher kann es gelegentlich zu unbeabsichtigten Nebeneffekten kommen.

Update für SETOF Variante:

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

Beachten Sie, dass ich, um dieselben Daten aus dem ursprünglichen Beispiel zu verwenden, jede der Spalten mit den entsprechenden Namen in myType aliasieren musste . Außerdem müssen Sie alle Spalten von mysales aufzählen Wenn Sie diesen Weg gehen, gibt es keinen einfachen Weg, CREATE TYPE foo LIKE tableBar zu erstellen obwohl Sie dies möglicherweise verwenden können, um einige der manuellen Arbeiten zum Aufzählen aller Namen/Typen zu erleichtern:

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 ;

was zurückgibt:

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