Можете да използвате почти всяка библиотека на Python в съхранена процедура или тригер на PL/Python.
Вижте документацията за PL/Python .
Концепции
Решаващият момент за разбиране е, че PL/Python е CPython (в PostgreSQL до и включително 9.3, така или иначе); той използва точно същия интерпретатор, който прави нормалният самостоятелен Python, той просто го зарежда като библиотека в PostgreSQL, поддържан. С няколко ограничения (посочени по-долу), ако работи с CPython, работи и с PL/Python.
Ако имате множество интерпретатори на Python, инсталирани на вашата система - версии, дистрибуции, 32-битови срещу 64-битови и т.н. - може да се наложи да се уверите, че инсталирате разширения и библиотеки в правилния, когато изпълнявате distutils скриптове и т.н., но това е относно това.
Тъй като можете да заредите всяка библиотека, налична за системния Python, няма причина да мислите, че NLTK би бил проблем, освен ако не знаете, че изисква неща като нишки, които всъщност не се препоръчват в бекенда на PostgreSQL. (Разбира се, опитах го и то „просто проработи“, вижте по-долу).
Една възможна загриженост е, че разходите за стартиране на нещо като NLTK може да са доста големи, вероятно искате да го заредите предварително PL/Python в postmaster и да импортирате модула във вашия код за настройка, така че да е готов, когато бекендовете стартират. Разберете, че postmaster е родителският процес на всички останали бекенди fork()
от, така че ако администраторът на пощата предварително зареди нещо, то е достъпно за задните части със значително намалени режийни разходи. Тествайте ефективността така или иначе.
Сигурност
Тъй като можете да зареждате произволни C библиотеки чрез PL/Python и тъй като интерпретаторът на Python няма реален модел на сигурност, plpythonu
е "недоверен" език. Скриптовете имат пълен и неограничен достъп до системата като postgres
потребител и може доста просто да заобиколи контролите за достъп в PostgreSQL. Поради очевидни причини за сигурност това означава, че функциите и тригерите на PL/Python могат да бъдат създадени само от суперпотребителя, въпреки че е доста разумно да GRANT
обикновените потребители могат да бягат внимателно написани функции, които са инсталирани от суперпотребителя.
Предимството е, че можете да правите почти всичко, което можете да правите в нормален Python, като имате предвид, че животът на интерпретатора на Python е този на връзката с базата данни (сесия). Threading не се препоръчва, но повечето други неща са добре.
PL/Python функциите трябва да бъдат написани с внимателна обработка на входа, трябва да се зададе search_path
когато извиквате SPI за изпълнение на заявки и т.н. Това се обсъжда повече в ръководството.
Ограничения
Продължителни или потенциално проблемни неща като DNS търсения, HTTP връзки към отдалечени системи, SMTP доставка на поща и т.н. обикновено трябва да се правят от помощен скрипт, използващ LISTEN
и NOTIFY
вместо задача в задния край, за да се запази производителността на PostgreSQL и да се избегне възпрепятстването на VACUUM
с много дълги транзакции. Можете да правите тези неща в задната част, но това просто не е страхотна идея.
Трябва да избягвате създаването на нишки в бекенда на PostgreSQL.
Не се опитвайте да заредите библиотека на Python, която ще зареди libpq
C библиотека. Това може да причини всякакви вълнуващи проблеми с бекенда. Когато говорите с PostgreSQL от PL/Python, използвайте SPI процедурите, а не обикновената клиентска библиотека.
Не правете много дълготрайни неща в бекенда, ще причините проблеми с вакуума.
Не зареждайте нищо, което може да зареди различна версия на вече заредена родна C библиотека – да речем различна libcrypto, libssl и т.н.
Не пишете директно във файлове в директорията с данни на PostgreSQL никога .
Функциите на PL/Python се изпълняват като postgres
системен потребител на операционната система, така че те нямат достъп до неща като домашната директория на потребителя или файлове от страната на клиента на връзката.
Резултат от теста
$ 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)
Така че, както казах:опитайте. Докато интерпретаторът на Python, който PostgreSQL използва за plpython, има инсталирани зависимости на nltk, той ще работи добре.
Забележка
PL/Python е CPython, но бих се радвал да видя алтернатива, базирана на PyPy, която може да изпълнява ненадежден код, използвайки функциите на пясъчната среда на PyPy.