【问题标题】:Can NLTK be used in a Postgres Python Stored ProcedureNLTK 可以在 Postgres Python 存储过程中使用吗
【发布时间】:2013-04-29 08:49:57
【问题描述】:

如果可以在 Postgres Python 存储过程或触发器中使用 NLTK,是否有人做过或什至没有做过

【问题讨论】:

    标签: postgresql nlp nltk


    【解决方案1】:

    您可以在 PL/Python 存储过程或触发器中使用几乎任何 Python 库。

    请参阅PL/Python documentation

    概念

    要理解的关键点是 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 邮件传递等长期运行或可能存在问题的事情通常应使用 LISTENNOTIFY 的帮助程序脚本完成,而不是按顺序在后端作业中完成以保持 PostgreSQL 的性能并避免通过大量长事务妨碍VACUUM。你可以在后端做这些事情,这不是一个好主意。

    您应该避免在 PostgreSQL 后端创建线程。

    不要尝试加载任何会加载 libpq C 库的 Python 库。这可能会导致后端出现各种令人兴奋的问题。从 PL/Python 与 PostgreSQL 对话时,使用 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)
    

    所以,正如我所说:试试吧。只要 PostgreSQL 用于 plpython 的 Python 解释器安装了 nltk 的依赖项,它就可以正常工作。

    注意

    PL/Python 是 CPython,但我希望看到基于 PyPy 的替代方案,它可以使用 PyPy 的沙盒功能运行不受信任的代码。

    【讨论】:

    • 不确定我是否理解您的回复。我已经阅读了您提供的链接,它实际上没有指定我可以看到的任何明确限制,因此问题;我错过了什么吗?
    • @user2064232 您希望找到什么限制?你在担心什么? 你试过了吗? (哦,刚刚注意到我的回答中可能存在措辞问题。已更正并详细说明了答案)。
    • “限制” 它不起作用; “担忧”我问 Streamhacker aka Jacob Perkins 关于在 Iron Python 中运行 NLTK 的问题,他说由于 numpy 和 C 库的依赖关系,它不会工作。 “我试过了吗”嗯,这就是我的帖子的重点,即如果有人尝试过并且失败了,我可能会节省一些时间,如果没有,我会尝试一下!显然答案是没有人尝试过或没有人知道答案!
    • @user2064232 C 库依赖和 numpy 在 PL/Python 中应该不是问题。
    • @user2064232 它工作正常,请参阅更新的答案。我有点失望,NLTK 似乎甚至没有正确标记 it's,但也许你必须为此设置一种语言或其他东西。
    猜你喜欢
    • 2011-07-20
    • 2020-04-03
    • 1970-01-01
    • 2011-12-30
    • 2011-03-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-17
    相关资源
    最近更新 更多