Puoi usare praticamente qualsiasi libreria Python in una stored procedure o trigger PL/Python.
Consulta la documentazione PL/Python .
Concetti
Il punto cruciale da capire è che PL/Python è CPython (in PostgreSQL fino a 9.3 incluso, comunque); usa esattamente lo stesso interprete del normale Python standalone, lo carica semplicemente come libreria nel supporto di PostgreSQL. Con alcune limitazioni (descritte di seguito), se funziona con CPython funziona con PL/Python.
Se hai più interpreti Python installati sul tuo sistema - versioni, distribuzioni, 32 bit vs 64 bit ecc. - Potrebbe essere necessario assicurarsi di installare estensioni e librerie in quella giusta quando si eseguono script distutils, ecc., ma è così a riguardo.
Dal momento che puoi caricare qualsiasi libreria disponibile per il sistema Python, non c'è motivo di pensare che NLTK sarebbe un problema a meno che tu non sappia che richiede cose come il threading che non sono realmente raccomandate in un backend PostgreSQL. (Abbastanza sicuro, l'ho provato e ha "funzionato", vedi sotto).
Una possibile preoccupazione è che il sovraccarico di avvio di qualcosa come NLTK potrebbe essere piuttosto grande, probabilmente vorrai precaricarlo PL/Python nel postmaster e importare il modulo nel tuo codice di installazione in modo che sia pronto quando iniziano i backend. Comprendi che il postmaster è il processo padre di tutti gli altri backend fork()
da, quindi se il postmaster precarica qualcosa è disponibile per i backend con spese generali notevolmente ridotte. Testare le prestazioni in entrambi i casi.
Sicurezza
Poiché puoi caricare librerie C arbitrarie tramite PL/Python e poiché l'interprete Python non ha un vero modello di sicurezza, plpythonu
è una lingua "non affidabile". Gli script hanno accesso completo e illimitato al sistema come postgres
utente e può semplicemente aggirare i controlli di accesso in PostgreSQL. Per ovvi motivi di sicurezza, ciò significa che le funzioni e i trigger PL/Python possono essere creati solo dal superutente, sebbene sia abbastanza ragionevole GRANT
utenti normali la possibilità di eseguire funzioni scritte con cura che sono state installate dal superutente.
Il vantaggio è che puoi fare praticamente tutto ciò che puoi fare in Python normale, tenendo presente che la durata dell'interprete Python è quella della connessione al database (sessione). Il threading non è raccomandato, ma la maggior parte delle altre cose va bene.
Le funzioni PL/Python devono essere scritte con un'attenta sanificazione dell'input, devono impostare search_path
quando si invoca l'SPI per eseguire query, ecc. Questo è discusso più dettagliatamente nel manuale.
Limiti
Cose di lunga durata o potenzialmente problematiche come ricerche DNS, connessioni HTTP a sistemi remoti, consegna di posta SMTP, ecc. In genere dovrebbero essere eseguite da uno script di supporto utilizzando LISTEN
e NOTIFY
piuttosto che un lavoro in-back-end per preservare le prestazioni di PostgreSQL ed evitare di ostacolare VACUUM
con molte transazioni lunghe. Puoi fare queste cose nel back-end, semplicemente non è una buona idea.
Dovresti evitare di creare thread all'interno del backend di PostgreSQL.
Non tentare di caricare alcuna libreria Python che caricherà libpq
libreria C. Ciò potrebbe causare ogni sorta di problemi eccitanti con il back-end. Quando parli con PostgreSQL da PL/Python, usa le routine SPI non una normale libreria client.
Non eseguire operazioni di lunga durata nel back-end, causerai problemi di vuoto.
Non caricare nulla che potrebbe caricare una versione diversa di una libreria C nativa già caricata, ad esempio una diversa libcrypto, libssl, ecc.
Non scrivere direttamente sui file nella directory dei dati di PostgreSQL, mai .
Le funzioni PL/Python vengono eseguite come postgres
utente di sistema sul sistema operativo, quindi non hanno accesso a cose come la home directory dell'utente o i file sul lato client della connessione.
Risultato del 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)
Quindi, come ho detto:provalo. Finché l'interprete Python utilizzato da PostgreSQL per plpython ha le dipendenze di nltk installate, funzionerà correttamente.
Nota
PL/Python è CPython, ma mi piacerebbe vedere un'alternativa basata su PyPy in grado di eseguire codice non affidabile utilizzando le funzionalità sandbox di PyPy.