sql >> Base de Datos >  >> RDS >> PostgreSQL

¿Se puede usar NLTK en un procedimiento almacenado de Postgres Python?

Puede usar prácticamente cualquier biblioteca de Python en un procedimiento almacenado o activador de PL/Python.

Consulte la documentación de PL/Python .

Conceptos

El punto crucial a entender es que PL/Python es CPython (en PostgreSQL hasta 9.3 inclusive, de todos modos); utiliza exactamente el mismo intérprete que Python independiente normal, simplemente lo carga como una biblioteca en el respaldo de PostgreSQL. Con algunas limitaciones (descritas a continuación), si funciona con CPython, funciona con PL/Python.

Si tiene varios intérpretes de Python instalados en su sistema (versiones, distribuciones, 32 bits frente a 64 bits, etc.), es posible que deba asegurarse de que está instalando extensiones y bibliotecas en el correcto cuando ejecuta scripts de distutils, etc., pero eso es al respecto.

Dado que puede cargar cualquier biblioteca disponible para el sistema Python, no hay razón para pensar que NLTK sería un problema a menos que sepa que requiere cosas como subprocesos que realmente no se recomiendan en un backend de PostgreSQL. (Efectivamente, lo probé y "simplemente funcionó", ver más abajo).

Una posible preocupación es que la sobrecarga de inicio de algo como NLTK podría ser bastante grande, probablemente desee precargar PL/Python en el postmaster e importar el módulo en su código de configuración para que esté listo cuando se inicien los backends. Comprenda que el postmaster es el proceso principal que todos los demás backends fork() from, por lo que si el postmaster precarga algo, está disponible para los backends con gastos generales muy reducidos. Pruebe el rendimiento de cualquier manera.

Seguridad

Debido a que puede cargar bibliotecas C arbitrarias a través de PL/Python y debido a que el intérprete de Python no tiene un modelo de seguridad real, plpythonu es un lenguaje "no confiable". Los scripts tienen acceso total y sin restricciones al sistema como postgres usuario y puede simplemente eludir los controles de acceso en PostgreSQL. Por obvias razones de seguridad, esto significa que las funciones y disparadores de PL/Python solo pueden ser creados por el superusuario, aunque es bastante razonable GRANT usuarios normales la capacidad de ejecutar funciones cuidadosamente escritas que fueron instaladas por el superusuario.

La ventaja es que puede hacer prácticamente cualquier cosa que pueda hacer en Python normal, teniendo en cuenta que la vida útil del intérprete de Python es la de la conexión a la base de datos (sesión). No se recomienda enhebrar, pero la mayoría de las otras cosas están bien.

Las funciones de PL/Python deben escribirse con cuidadoso saneamiento de entrada, debe establecer search_path al invocar el SPI para ejecutar consultas, etc. Esto se trata más en el manual.

Limitaciones

Las cosas de ejecución prolongada o potencialmente problemáticas, como las búsquedas de DNS, las conexiones HTTP a sistemas remotos, la entrega de correo SMTP, etc., generalmente deben realizarse desde un script de ayuda usando LISTEN y NOTIFY en lugar de un trabajo interno para preservar el rendimiento de PostgreSQL y evitar obstaculizar VACUUM con muchas transacciones largas. Puede hacer estas cosas en el backend, simplemente no es una gran idea.

Debe evitar crear subprocesos dentro del backend de PostgreSQL.

No intente cargar ninguna biblioteca de Python que cargue libpq biblioteca C. Esto podría causar todo tipo de problemas emocionantes con el backend. Cuando hable con PostgreSQL desde PL/Python, use las rutinas SPI, no una biblioteca cliente normal.

No haga cosas de larga duración en el backend, causará problemas de vacío.

No cargue nada que pueda cargar una versión diferente de una biblioteca C nativa ya cargada, digamos una libcrypto, libssl, etc. diferente.

No escriba directamente en archivos en el directorio de datos de PostgreSQL, nunca .

Las funciones de PL/Python se ejecutan como postgres usuario del sistema en el sistema operativo, por lo que no tienen acceso a cosas como el directorio de inicio del usuario o archivos en el lado del cliente de la conexión.

Resultado de la prueba

$ 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)

Entonces, como dije:Pruébalo. Siempre que el intérprete de Python que PostgreSQL esté usando para plpython tenga instaladas las dependencias de nltk, funcionará bien.

Nota

PL/Python es CPython, pero me encantaría ver una alternativa basada en PyPy que pueda ejecutar código que no sea de confianza usando las funciones de sandbox de PyPy.