PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

O NLTK pode ser usado em um procedimento armazenado Postgres Python


Você pode usar praticamente qualquer biblioteca Python em um procedimento armazenado ou gatilho PL/Python.

Consulte a documentação do PL/Python .

Conceitos


O ponto crucial a ser entendido é que PL/Python é CPython (no PostgreSQL até 9.3 inclusive); ele usa exatamente o mesmo interpretador que o Python autônomo normal, ele apenas o carrega como uma biblioteca no PostgreSQL apoiado. Com algumas limitações (descritas abaixo), se funciona com CPython, funciona com PL/Python.

Se você tiver vários intérpretes Python instalados em seu sistema - versões, distribuições, 32 bits vs 64 bits etc - talvez seja necessário ter certeza de que está instalando extensões e bibliotecas no caminho certo ao executar scripts distutils etc. sobre isso.

Como você pode carregar qualquer biblioteca disponível para o sistema Python, não há razão para pensar que o NLTK seria um problema, a menos que você saiba que ele requer coisas como threading que não são realmente recomendadas em um backend do PostgreSQL. (Com certeza, eu tentei e "simplesmente funcionou", veja abaixo).

Uma possível preocupação é que a sobrecarga de inicialização de algo como NLTK pode ser muito grande, você provavelmente deseja pré-carregar PL/Python no postmaster e importar o módulo em seu código de configuração para que esteja pronto quando os back-ends forem iniciados. Entenda que o postmaster é o processo pai que todos os outros backends fork() de, portanto, se o postmaster pré-carregar algo, ele estará disponível para os back-ends com despesas gerais bastante reduzidas. Teste o desempenho de qualquer maneira.

Segurança


Como você pode carregar bibliotecas C arbitrárias via PL/Python e porque o interpretador Python não possui um modelo de segurança real, plpythonu é uma linguagem "não confiável". Os scripts têm acesso total e irrestrito ao sistema como o postgres user e pode simplesmente ignorar os controles de acesso no PostgreSQL. Por razões óbvias de segurança, isso significa que as funções e gatilhos PL/Python só podem ser criados pelo superusuário, embora seja bastante razoável GRANT usuários normais a capacidade de executar funções cuidadosamente escritas que foram instaladas pelo superusuário.

A vantagem é que você pode fazer praticamente qualquer coisa que você pode fazer em Python normal, tendo em mente que o tempo de vida do interpretador Python é o da conexão com o banco de dados (sessão). Threading não é recomendado, mas a maioria das outras coisas estão bem.

As funções PL/Python devem ser escritas com cuidadosa limpeza de entrada, devem definir search_path ao invocar o SPI para executar consultas, etc. Isso é discutido mais detalhadamente no manual.

Limitações


Coisas de longa duração ou potencialmente problemáticas, como pesquisas de DNS, conexões HTTP para sistemas remotos, entrega de correio SMTP, etc, geralmente devem ser feitas a partir de um script auxiliar usando LISTEN e NOTIFY em vez de um trabalho de back-end para preservar o desempenho do PostgreSQL e evitar prejudicar o VACUUM com muitas transações longas. Você pode fazer essas coisas no back-end, mas não é uma boa ideia.

Você deve evitar criar threads no backend do PostgreSQL.

Não tente carregar nenhuma biblioteca Python que carregue a libpq biblioteca C. Isso pode causar todos os tipos de problemas interessantes com o back-end. Ao falar com o PostgreSQL a partir de PL/Python, use as rotinas SPI e não uma biblioteca cliente comum.

Não faça coisas muito longas no backend, você causará problemas de vácuo.

Não carregue nada que possa carregar uma versão diferente de uma biblioteca C nativa já carregada - digamos, uma libcrypto, libssl, etc.

Não escreva diretamente em arquivos no diretório de dados do PostgreSQL, nunca .

As funções PL/Python são executadas como postgres usuário do sistema no sistema operacional, para que eles não tenham acesso a coisas como o diretório inicial do usuário ou arquivos no lado do cliente da conexão.

Resultado do teste

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

Então, como eu disse:Experimente. Contanto que o interpretador Python que o PostgreSQL está usando para plpython tenha as dependências do nltk instaladas, ele funcionará bem.

Observação


PL/Python é CPython, mas eu adoraria ver uma alternativa baseada em PyPy que pode executar código não confiável usando os recursos de sandbox do PyPy.