Les fonctions PL/Python sont déclarées via la syntaxe standard CREATE FUNCTION :
CREATE FUNCTIONnom_fonction
(liste-arguments
) RETURNSreturn-type
AS $$ # corps de la fonction PL/Python $$ LANGUAGE plpythonu;
Le corps d'une fonction est tout simplement un script Python. Quand la
fonction est appelée, ses arguments sont passés au script Python comme des
éléments de la liste args
; les arguments nommés
sont en plus passés comme des variables ordinaires. L'utilisation des
arguments nommés est beaucoup plus lisible. Le résultat est renvoyé
par le code Python de la façon habituelle, avec return
ou
yield
(dans le cas d'une instruction avec un ensemble
de résultats). Si vous ne fournissez pas une valeur de retour, Python
renvoie la valeur par défaut None
.
PL/Python traduit la valeur None
de Python comme une valeur NULL SQL.
Par exemple, une fonction renvoyant le plus grand de deux entiers peut être définie ainsi :
CREATE FUNCTION pymax (a integer, b integer) RETURNS integer AS $$ if a > b: return a return b $$ LANGUAGE plpythonu;
Le code Python donné comme corps de la définition de fonction est transformé en fonction Python. Par exemple, le code ci-dessus devient :
def __plpython_procedure_pymax_23456(): if a > b: return a return b
en supposant que 23456 est l'OID affecté à la fonction par PostgreSQL.
Les arguments sont définis comme des variables globales. Conséquence subtile des règles sur la portée de variables dans Python, il n'est pas possible de réaffecter une variable à l'intérieur d'une fonction en conservant son nom, sauf si elle est préalablement déclarée comme globale à l'intérieur du bloc. Ainsi, l'exemple suivant ne fonctionnera pas :
CREATE FUNCTION pystrip(x text) RETURNS text AS $$ x = x.strip() # error return x $$ LANGUAGE plpythonu;
car affecter la variable x
la transforme en variable
locale pour ce bloc et que, par conséquent, la variable x
de l'expression de droite fait référence à une variable locale
x
non encore définie, et non pas au paramètre de la
fonction PL/Python. L'utilisation du mot-clé global
permet
de résoudre le problème :
CREATE FUNCTION pystrip(x text) RETURNS text AS $$ global x x = x.strip() # ok now return x $$ LANGUAGE plpythonu;
Cependant, il vaut mieux ne pas trop s'appuyer sur ce détail d'implémentation de PL/Python. Il est préférable de traiter les paramètres de fonction comme étant en lecture seule.