PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

PL/Python e postgreSQL:qual è il modo migliore per restituire una tabella con molte colonne?

Prova questo:

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

che restituisce:

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)

Qualcosa da considerare per MPP come Greenplum e HAWQ è cercare funzioni che prendano i dati come argomento e restituiscano un risultato, piuttosto che originare i dati nella funzione stessa. Lo stesso codice viene eseguito su ogni segmento, quindi occasionalmente possono verificarsi effetti collaterali indesiderati.

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

Nota, per utilizzare gli stessi dati dell'esempio originale, ho dovuto alias ciascuna delle colonne ai nomi corrispondenti in myType . Inoltre, dovrai enumerare tutte le colonne di mysales se si segue questa strada, non esiste un modo semplice per CREATE TYPE foo LIKE tableBar anche se potresti essere in grado di usarlo per alleviare parte del lavoro manuale di enumerare tutti i nomi/tipi:

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 ;

che restituisce:

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