40.3. Accès à la base de données

Le module du langage PL/Python importe automatiquement un module Python appelé plpy. Les fonctions et constantes de ce module vous sont accessibles dans le code Python via plpy.foo. Actuellement, plpy implémente les fonctions plpy.debug("msg"), plpy.log("msg"), plpy.info("msg"), plpy.notice("msg"), plpy.warning("msg"), plpy.error("msg") et plpy.fatal("msg"). Elles sont pratiquement équivalentes à l'appel de elog(LEVEL, "msg") depuis un code C. plpy.error et plpy.fatal lèvent une exception Python qui, si elle n'est pas récupérée, demande au module PL/Python d'appeler elog(ERROR, msg) lorsque le gestionnaire de fonction revient de l'interpréteur Python. Un saut long en dehors de l'interpréteur Python n'est probablement pas bon. raise plpy.ERROR("msg") et raise plpy.FATAL("msg") sont équivalents, respectivement, à l'appel de plpy.error et plpy.fatal.

De plus, le module plpy fournit deux fonctions appelées execute et prepare. Appeler plpy.execute avec une chaîne de requête et un argument de limite optionnel fait que la requête est lancée et que le résultat est renvoyé dans un objet résultat. L'objet résultat émule une liste ou un objet dictionnaire. L'objet résultat est accessible par le numéro de ligne et le nom de la colonne. Il a plusieurs méthodes supplémentaires : nrows qui renvoie le nombre de lignes retournées par la requête et status qui est le code de retour de SPI_exec(). L'objet résultat peut être modifié.

Par exemple,

rv = plpy.execute("SELECT * FROM ma_table", 5)

renvoie cinq lignes de ma_table. Si ma_table dispose d'une colonne ma_colonne, elle sera accessible avec

foo = rv[i]["ma_colonne"]

La seconde fonction, plpy.prepare, prépare le plan d'exécution pour une requête. Il est appelé avec une chaîne contenant la requête et une liste des types de paramètres si vous avez des références de paramètres dans la requête. Par exemple :

plan = plpy.prepare("SELECT nom FROM mes_utilisateurs WHERE prenom = $1", [
"text" ])

text est le type de la variable que vous voulez passer via $1. Après avoir préparé une instruction, vous utilisez la fonction plpy.execute pour l'exécuter :

rv = plpy.execute(plan, [ "nom" ], 5)

Le troisième argument est la limite et est optionnelle.

Dans la version actuelle, toute erreur de base de données rencontrée lors de l'exécution d'une fonction PL/Python résultera en la fin immédiate de cette fonction par le serveur ; il n'est pas possible de récupérer les conditions d'erreurs en utilisant les constructions try ... catch de Python. Par exemple, une erreur de syntaxe dans une instruction SQL passée à plpy.execute terminera la fonction. Ce comportement pourrait changer dans une prochaine version.

Lorsque vous préparez un plan en utilisant le module PL/Python, il est automatiquement sauvegardé. Lisez la documentation SPI (Chapitre 41) pour une description de ce que cela signifie. Pour faire réellement usage de ceci dans les appels de fonction, vous avez besoin d'utiliser un des dictionnaires à stockage permanent SD ou GD (voir le Section 40.1). Par exemple :

CREATE FUNCTION utiliseplansauvegarde() RETURNS trigger AS '
    if SD.has_key("plan"):
        plan = SD["plan"]
    else:
        plan = plpy.prepare("SELECT 1")
        SD["plan"] = plan
    # reste de la fonction
' LANGUAGE plpythonu;