V uložené proceduře nebo spouštěči PL/Pythonu můžete použít téměř jakoukoli knihovnu Pythonu.
Viz dokumentace PL/Python .
Koncepty
Klíčovým bodem k pochopení je, že PL/Python je CPython (v PostgreSQL až do 9.3 včetně); používá přesně stejný interpret jako normální samostatný Python, jen ho načte jako knihovnu do PostgreSQL zálohovaného. S několika omezeními (nastíněnými níže), pokud to funguje s CPythonem, funguje i s PL/Pythonem.
Pokud máte ve svém systému nainstalovaných více interpretů Pythonu – verze, distribuce, 32bitové vs 64bitové atd. – možná se budete muset ujistit, že instalujete rozšíření a knihovny do správného, když spouštíte skripty distutils atd., ale to je o tom.
Vzhledem k tomu, že můžete načíst libovolnou knihovnu dostupnou pro systémový Python, není důvod si myslet, že by NLTK byl problém, pokud nevíte, že vyžaduje věci jako vlákno, které se v backendu PostgreSQL opravdu nedoporučuje. (Jistě, zkusil jsem to a "prostě to fungovalo", viz níže).
Jednou z možných obav je, že spouštěcí režie něčeho, jako je NLTK, může být docela velká. Pravděpodobně budete chtít přednačíst PL/Python v postmasteru a importovat modul do vašeho instalačního kódu, aby byl připraven, když se spustí backendy. Pochopte, že postmaster je nadřazeným procesem všech ostatních backendů fork()
od, takže pokud postmaster něco předem nahraje, je to dostupné pro backendy s výrazně sníženou režií. Otestujte výkon v obou směrech.
Zabezpečení
Protože můžete načíst libovolné knihovny C přes PL/Python a protože interpret Pythonu nemá žádný skutečný bezpečnostní model, plpythonu
je "nedůvěryhodný" jazyk. Skripty mají plný a neomezený přístup do systému jako postgres
a může poměrně jednoduše obejít řízení přístupu v PostgreSQL. Ze zřejmých bezpečnostních důvodů to znamená, že funkce a spouštěče PL/Pythonu může vytvářet pouze superuživatel, i když je docela rozumné GRANT
běžným uživatelům možnost spustit pečlivě napsané funkce, které byly nainstalovány superuživatelem.
Výhodou je, že můžete dělat v podstatě cokoli, co můžete dělat v normálním Pythonu, přičemž je třeba mít na paměti, že životnost tlumočníka Pythonu je životnost databázového připojení (relace). Řezání závitů se nedoporučuje, ale většina ostatních věcí je v pořádku.
Funkce PL/Python musí být napsány s pečlivou sanitací vstupu, musí být nastavena search_path
při vyvolání SPI pro spouštění dotazů atd. Více je to popsáno v manuálu.
Omezení
Dlouhotrvající nebo potenciálně problematické věci, jako je vyhledávání DNS, připojení HTTP ke vzdáleným systémům, doručování pošty SMTP atd., by se obecně měly provádět z pomocného skriptu pomocí LISTEN
a NOTIFY
spíše než úloha v backendu, aby se zachoval výkon PostgreSQL a zabránilo se omezování VACUUM
se spoustou dlouhých transakcí. Tyto věci můžete dělat v backendu, prostě to není skvělý nápad.
Měli byste se vyhnout vytváření vláken v backendu PostgreSQL.
Nepokoušejte se načíst žádnou knihovnu Pythonu, která načte libpq
C knihovna. To by mohlo způsobit nejrůznější vzrušující problémy s backendem. Při komunikaci s PostgreSQL z PL/Pythonu používejte rutiny SPI, nikoli běžnou klientskou knihovnu.
Nedělejte v backendu příliš dlouhotrvající věci, způsobíte si problémy s vakuem.
Nenahrávejte nic, co by mohlo načíst jinou verzi již načtené nativní knihovny C – řekněme jiné libcrypto, libssl atd.
Nezapisujte přímo do souborů v datovém adresáři PostgreSQL, nikdy .
Funkce PL/Python běží jako postgres
systémový uživatel na OS, takže nemají přístup k věcem, jako je domovský adresář uživatele nebo soubory na klientské straně připojení.
Výsledek testu
$ 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)
Takže, jak jsem řekl:Zkuste to. Pokud má Pythonový interpret PostgreSQL pro plpython nainstalované závislosti nltk, bude fungovat dobře.
Poznámka
PL/Python je CPython, ale rád bych viděl alternativu založenou na PyPy, která dokáže spouštět nedůvěryhodný kód pomocí funkcí sandboxu PyPy.