Documentazione di PostgreSQL 9.0 > Programmazione del server > PL/Python - linguaggio procedurale python > Valori dei dati
PrecedenteFunzioni PL/PythonSharing DataSuccessivo

42.3. Valori dei dati

Parlando in generale, lo scopo di PL/Puthon è di fornire una mappatura «naturale» tra PostgreSQL e il mondo di Python. Questo prevede le seguenti regole di mappatura dei dati.

42.3.1. Mappatura dei tipi di dato

Gli argomenti della funzione sono convertiti dai loro tipi PostgreSQL a tipi Python corrispondenti:

  • Il boolean PostgreSQL è convertito in un bool Python.

  • smallint e int di PostgreSQL sono convertiti a int Python. bigint PostgreSQL è convertito a long in Python 2 e a int in Python 3.

  • I real, double e numeric PostgreSQL sono convertiti in float Python. Notare che per il numeric vengono perse informazioni e possono portare a risultati non corretti. Questo potrebbe essere corretto in una versione futura.

  • I bytea di PostgreSQL sono convertiti a str Python 2 e a bytes in Python 3. In Python 2, la stringa dovrebbe essere trattata come una sequenza di byte senza nessuna codifica dei caratteri.

  • Tutti gli altri tipi di dato, incluso i tipi di stringa di caratteri PostgreSQL, vengono convertiti a una str Python. In Python 2, questa stringa sarà nella codifica del server PostgreSQL; in Python 3, sarà una stringa Unicode come tutte le stringhe.

  • Per tipi di dato non scalari, si veda sotto.

I valori di ritorno della funzione sono convertiti ai tipi di ritorno dichiarati da PostgreSQL come segue:

  • Quando un tipo di ritorno PostgreSQL è boolean, il valore di ritorno sarà valutato per verità in accordo alle regole Python. Cioè, 0 e stringhe vuote sono false, ma in particolare 'f' è true.

  • Quando il tipo di ritorno di PostgreSQL è bytea, il valore di ritorno sarà convertito a una stringa (Python 2) o byte (Python 3) usando le rispettive builtin, con il risultato convertito a bytea.

  • Per tutti gli altri tipi di ritorno di PostgreSQL, il valore Python restituito è convertito a una stringa usando la funzione Python incorporata str, e il risultato è passato alla funzione di input del tipo di dato PostgreSQL.

    Le stringhe in Python 2 sono richieste essere nella codifica del server PostgreSQL quando sono passate a PostgreSQL. Le stringhe che non sono valide nella codifica attuale del server genereranno un errore, ma non tutti gli errori di codifica possono essere trovati, quindi risulteranno comunque dati sporchi quando non è fatto correttamente. Le stringhe Unicode vengono convertite alla codifica corretta automaticamente, quindi può essere più sicuro è più conveniente usare quelle. In Python 3, tutte le stringhe sono stringhe Unicode.

  • Per tipi di dato non scalari, si veda sotto.

Si noti che le discrepanze tra il tipo di ritorno dichiarato da PostgreSQL e il tipo di dato Python dell'effettivo oggetto ritornato non sono segnalate; il valore sarà convertito in ogni caso.

[Suggerimento]

Suggerimento

Le funzioni PL/Python non possono ritornare nè il il tipo RECORD e nemmeno SETOF RECORD. Un workaround è di scrivere una funzione PL/pgSQL che crea una tabella temporanea, fargli chiamare la funzione PL/Python per riempire la tabella, e quindi far si che la funzione PL/pgSQL ritorni il generico RECORD dalla tabella temporanea.

42.3.2. Null, None

Se un valore SQL null viene passato a una funzione, il valore dell'argomento apparirà come None in Python. La definizione della funzione sopra ritornerà la risposta sbagliata per input null. Si potrebbe aggiungere STRICT alla definizione della funzione per far si che PostgreSQL™ faccia qualcosa di più ragionevole: se è passato un valore null, la funzione non sarà chiamata per niente, ma restituirà automaticamente un risultato null. Alternativamente, si potrebbero controllare input null nel corpo della funzione:

CREATE FUNCTION pymax (a integer, b integer)
  RETURNS integer
AS $$
  if (a is None) or (b is None):
    return None
  if a > b:
    return a
  return b
$$ LANGUAGE plpythonu;

Come mostrato sopra, per ritornare un valore SQL null da una funzione PL/Python, ritornare il valore None. Questo può essere fatto sia che la funzione sia strict che non.

42.3.3. Array, List

I valori di array SQL sono passati in PL/Python come una list Python. Per ritornare un valore di array SQL fuori da una funzione PL/Python, restituire una sequenza Python, per esempio una list o una tupla:

CREATE FUNCTION return_arr()
  RETURNS int[]
AS $$
return (1, 2, 3, 4, 5)
$$ LANGUAGE plpythonu;

SELECT return_arr();
 return_arr  
-------------
 {1,2,3,4,5}
(1 row)

Notare che in Python, le stringhe sono sequenze, che possono avere effetti indesiderati che potrebbero essere familiari ai programmatori Python:

CREATE FUNCTION return_str_arr()
  RETURNS varchar[]
AS $$
return "hello"
$$ LANGUAGE plpythonu;

SELECT return_str_arr();
 return_str_arr
----------------
 {h,e,l,l,o}
(1 row)

42.3.4. Tipi composti

Composite-type arguments are passed to the function as Python mappings. The element names of the mapping are the attribute names of the composite type. If an attribute in the passed row has the null value, it has the value Se un attributo nella riga passata ha il valore null, ha il valore None nella mappatura. Ecco un esempio:

CREATE TABLE employee (
  name text,
  salary integer,
  age integer
);

CREATE FUNCTION overpaid (e employee)
  RETURNS boolean
AS $$
  if e["salary"] > 200000:
    return True
  if (e["age"] < 30) and (e["salary"] > 100000):
    return True
  return False
$$ LANGUAGE plpythonu;

Ci sono molti modi di restituire tipi riga o tipi composti da una funzione Python. Gli esempi seguenti assumono che si abbia:

CREATE TYPE named_value AS (
  name   text,
  value  integer
);

Un risultato composto può essere restituito come:

Il tipo della sequenza (una tupla o un elenco, ma non un insieme perchè non è indicizzabile)

Gli oggetti della sequenza restituiti devono avere lo stesso numero di elementi dato che il risultato composto ha campi. L'elemento con indice 0 è assegnato al primo campo del tipo composto, 1 al secondo e così via. Per esempio:

CREATE FUNCTION make_pair (name text, value integer)
  RETURNS named_value
AS $$
  return [ name, value ]
  # or alternatively, as tuple: return ( name, value )
$$ LANGUAGE plpythonu;

Per restituire un null SQL per qualsiasi colonna, inserire None alla posizione corrispondente.

Mappatura (dizionario)

Il valore per ogni colonna del tipo del risultato è ricavata dalla mappatura con il nome della colonna come chiave. Esempio:

CREATE FUNCTION make_pair (name text, value integer)
  RETURNS named_value
AS $$
  return { "name": name, "value": value }
$$ LANGUAGE plpythonu;

Qualsiasi ulteriore coppia del dizionario chiave/valore è ignorata. Le chiavi mancanti sono trattate come errori. Per restituire un valore null SQL da qualsiasi colonna, inserire None con il corrispondente nome della colonna come chiave.

Oggetto (qualsiasi oggetto che fornisce il metodo __getattr__)

Questo funzione allo stesso modo della mappatura. Esempio:

CREATE FUNCTION make_pair (name text, value integer)
  RETURNS named_value
AS $$
  class named_value:
    def __init__ (self, n, v):
      self.name = n
      self.value = v
  return named_value(name, value)

  # or simply
  class nv: pass
  nv.name = name
  nv.value = value
  return nv
$$ LANGUAGE plpythonu;

42.3.5. Funzioni che ritornano insiemi

Una funzione PL/Python può anche ritornare insiemi di tipi scalari o composti. Ci sono diversi modi di ottenere questo dato che l'oggetto ritornato internamente è convertito a un iteratore. Gli esempi seguenti assumono che si abbia il tipo composto:

CREATE TYPE greeting AS (
  how text,
  who text
);

A set result can be returned from a:

Sequence type (tuple, list, set)

CREATE FUNCTION greet (how text)
  RETURNS SETOF greeting
AS $$
  # return tuple containing lists as composite types
  # all other combinations work also
  return ( [ how, "World" ], [ how, "PostgreSQL" ], [ how, "PL/Python" ] )
$$ LANGUAGE plpythonu;

Iterator (any object providing __iter__ and next methods)

CREATE FUNCTION greet (how text)
  RETURNS SETOF greeting
AS $$
  class producer:
    def __init__ (self, how, who):
      self.how = how
      self.who = who
      self.ndx = -1

    def __iter__ (self):
      return self

    def next (self):
      self.ndx += 1
      if self.ndx == len(self.who):
        raise StopIteration
      return ( self.how, self.who[self.ndx] )

  return producer(how, [ "World", "PostgreSQL", "PL/Python" ])
$$ LANGUAGE plpythonu;

Generator (yield)

CREATE FUNCTION greet (how text)
  RETURNS SETOF greeting
AS $$
  for who in [ "World", "PostgreSQL", "PL/Python" ]:
    yield ( how, who )
$$ LANGUAGE plpythonu;

[Avvertimento]

Avvertimento

A causa del bug #1483133 di Python, alcune versioni di debug di Python 2.4 (configurati e compilati con opzione --with-pydebug) sono conosciute per provocare blocchi del server PostgreSQL™ quando si usa un iteratore per restituire un insieme. Versioni non patchate di Fedora 4 contengono questo bug. Non succede in versioni in produzione di Python o su versioni con patch di Fedora 4.

Documentazione di PostgreSQL 9.0 > Programmazione del server > PL/Python - linguaggio procedurale python > Valori dei dati
PrecedenteFunzioni PL/PythonSharing DataSuccessivo