PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

PL/Python &postgreSQL :Quelle est la meilleure façon de renvoyer une table de plusieurs colonnes ?

Essayez ceci :

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

qui renvoie :

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)

Quelque chose à considérer pour MPP comme Greenplum et HAWQ est de rechercher des fonctions qui prennent des données comme argument et renvoient un résultat, plutôt que de générer les données dans la fonction elle-même. Le même code s'exécute sur chaque segment, ce qui peut parfois entraîner des effets secondaires imprévus.

Mise à jour pour 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';

Remarque, pour utiliser les mêmes données de l'exemple d'origine, j'ai dû alias chacune des colonnes aux noms correspondants dans myType . De plus, vous devrez énumérer toutes les colonnes de mysales si vous suivez cette voie - il n'y a pas de moyen simple de CREATE TYPE foo LIKE tableBar bien que vous puissiez l'utiliser pour alléger une partie du travail manuel d'énumération de tous les noms/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 ;

qui renvoie :

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