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

NLTK peut-il être utilisé dans une procédure stockée Python Postgres

Vous pouvez utiliser à peu près n'importe quelle bibliothèque Python dans une procédure stockée ou un déclencheur PL/Python.

Voir la documentation PL/Python .

Concepts

Le point crucial à comprendre est que PL/Python est CPython (dans PostgreSQL jusqu'à 9.3 inclus, de toute façon); il utilise exactement le même interpréteur que le Python autonome normal, il le charge simplement en tant que bibliothèque dans le support PostgreSQL. Avec quelques limitations (décrites ci-dessous), si cela fonctionne avec CPython, cela fonctionne avec PL/Python.

Si vous avez plusieurs interpréteurs Python installés sur votre système - versions, distributions, 32 bits vs 64 bits, etc. - vous devrez peut-être vous assurer que vous installez les extensions et les bibliothèques dans la bonne lors de l'exécution des scripts distutils, etc., mais c'est à ce sujet.

Étant donné que vous pouvez charger n'importe quelle bibliothèque disponible pour le système Python, il n'y a aucune raison de penser que NLTK serait un problème à moins que vous ne sachiez qu'il nécessite des choses comme le threading qui ne sont pas vraiment recommandés dans un backend PostgreSQL. (Effectivement, je l'ai essayé et ça "a juste fonctionné", voir ci-dessous).

Une préoccupation possible est que la surcharge de démarrage de quelque chose comme NLTK peut être assez importante, vous voudrez probablement le précharger PL/Python dans le postmaster et importer le module dans votre code d'installation afin qu'il soit prêt lorsque les backends démarrent. Comprenez que le postmaster est le processus parent que tous les autres backends fork() de, donc si le postmaster précharge quelque chose, il est disponible pour les backends avec des frais généraux considérablement réduits. Testez les performances dans tous les cas.

Sécurité

Parce que vous pouvez charger des bibliothèques C arbitraires via PL/Python et parce que l'interpréteur Python n'a pas de véritable modèle de sécurité, plpythonu est un langage "non fiable". Les scripts ont un accès complet et illimité au système en tant que postgres utilisateur et peut contourner assez simplement les contrôles d'accès dans PostgreSQL. Pour des raisons de sécurité évidentes, cela signifie que les fonctions et les déclencheurs PL/Python ne peuvent être créés que par le superutilisateur, bien qu'il soit tout à fait raisonnable de GRANT les utilisateurs normaux la possibilité de exécuter fonctions soigneusement écrites qui ont été installées par le superutilisateur.

L'avantage est que vous pouvez faire à peu près tout ce que vous pouvez faire en Python normal, en gardant à l'esprit que la durée de vie de l'interpréteur Python est celle de la connexion à la base de données (session). Le filetage n'est pas recommandé, mais la plupart des autres choses vont bien.

Les fonctions PL/Python doivent être écrites avec un assainissement minutieux des entrées, doivent définir search_path lors de l'appel du SPI pour exécuter des requêtes, etc. Ceci est discuté plus en détail dans le manuel.

Limites

Les opérations de longue durée ou potentiellement problématiques telles que les recherches DNS, les connexions HTTP à des systèmes distants, la livraison de courrier SMTP, etc. doivent généralement être effectuées à partir d'un script d'assistance à l'aide de LISTEN. et NOTIFY plutôt qu'un travail en backend afin de préserver les performances de PostgreSQL et d'éviter d'entraver VACUUM avec beaucoup de longues transactions. Vous pouvez faire ces choses dans le backend, ce n'est tout simplement pas une bonne idée.

Vous devez éviter de créer des threads dans le backend PostgreSQL.

N'essayez pas de charger une bibliothèque Python qui chargerait le libpq bibliothèque C. Cela pourrait causer toutes sortes de problèmes passionnants avec le backend. Lorsque vous parlez à PostgreSQL depuis PL/Python, utilisez les routines SPI et non une bibliothèque cliente standard.

Ne faites pas de choses très longues dans le backend, vous causerez des problèmes de vide.

Ne chargez rien qui pourrait charger une version différente d'une bibliothèque C native déjà chargée - disons une autre libcrypto, libssl, etc.

N'écrivez pas directement dans les fichiers du répertoire de données PostgreSQL, jamais .

Les fonctions PL/Python s'exécutent en tant que postgres utilisateur système sur le système d'exploitation, afin qu'il n'ait pas accès à des éléments tels que le répertoire personnel de l'utilisateur ou les fichiers du côté client de la connexion.

Résultat du test

$ yum install python-nltk python-nltk
$ psql -U postgres regress

regress=# CREATE LANGUAGE plpythonu;

regress=# CREATE OR REPLACE FUNCTION nltk_word_tokenize(word text) RETURNS text[] AS $$
          import nltk
          return nltk.word_tokenize(word)
          $$ LANGUAGE plpythonu;

regress=# SELECT nltk_word_tokenize('This is a test, it''s going to work fine');
              nltk_word_tokenize               
-----------------------------------------------
 {This,is,a,test,",",it,'s,going,to,work,fine}
(1 row)

Donc, comme je l'ai dit:essayez-le. Tant que l'interpréteur Python que PostgreSQL utilise pour plpython a les dépendances de nltk installées, cela fonctionnera correctement.

Remarque

PL/Python est CPython, mais j'aimerais voir une alternative basée sur PyPy qui peut exécuter du code non fiable à l'aide des fonctionnalités de bac à sable de PyPy.