概念
要理解的关键点是PL / Python是CPython(无论如何都在Postgresql中包括9.3);它使用与普通独立Python完全相同的解释器,它只是将它作为库加载到Postgresql支持的.有一些限制(如下所述),如果它适用于CPython,它可以与PL / Python一起使用.
如果您的系统上安装了多个Python解释器 – 版本,发行版,32位与64位等 – 您可能需要确保在运行distutils脚本等时将扩展和库安装到正确的解释器中,但这是关于它.
由于您可以加载任何可用于系统Python的库,因此没有理由认为NLTK会成为一个问题,除非您知道它需要在Postgresql后端中不真正推荐的线程之类的东西. (果然,我尝试了它并且它“正常工作”,见下文).
一个可能的问题是像NLTK这样的东西的启动开销可能很大,你可能想要在postmaster中预加载PL / Python并在你的设置代码中导入模块,以便在后端启动时准备就绪.理解postmaster是所有其他后端fork()的父进程,所以如果postmaster预加载了后端可用的东西,大大减少了开销.无论如何测试性能.
安全
因为您可以通过PL / Python加载任意C库,并且因为Python解释器没有真正的安全模型,所以plpythonu是一种“不受信任”的语言.作为postgres用户,脚本可以完全和不受限制地访问系统,并且可以简单地绕过Postgresql中的访问控制.出于明显的安全原因,这意味着PL / Python函数和触发器可能只能由超级用户创建,尽管GRANT普通用户能够运行由超级用户安装的精心编写的函数是非常合理的.
好处是你可以在普通的Python中做很多事情,记住Python解释器的生命周期是数据库连接(会话)的生命周期.不建议使用线程,但大多数其他事情都没问题.
PL / Python函数必须使用仔细的输入卫生编写,必须在调用SPI以运行查询时设置search_path等.本手册中将对此进行更多讨论.
限制
长时间运行或可能存在问题的事情,如DNS查找,到远程系统的HTTP连接,SMTP邮件传递等,通常应该使用LISTEN和NOTIFY而不是后端作业从助手脚本完成,以保持Postgresql的性能并避免妨碍VACUUM有很多长期交易.你可以在后端做这些事情,这不是一个好主意.
您应该避免在Postgresql后端中创建线程.
不要尝试加载任何将加载libpq C库的Python库.这可能会导致后端出现各种令人兴奋的问题.当从PL / Python与Postgresql交谈时,使用SPI例程而不是常规客户端库.
不要在后端做很长时间的事情,否则会造成真空问题.
不要加载任何可能加载已加载的本机C库的不同版本的东西 – 例如不同的libcrypto,libssl等.
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的沙箱功能运行不受信任的代码.