【问题标题】:PostgreSQL PL/Python: call stored procedure in virtualenvPostgreSQL PL/Python:在 virtualenv 中调用存储过程
【发布时间】:2012-03-06 15:10:40
【问题描述】:

当我在我的 Python 应用程序中调用 PostgreSQL PL/Python 存储过程时,它似乎在以用户 postgres 运行的单独进程中执行。到目前为止,这只产生了一个副作用,即我必须让我的日志文件对我自己和数据库用户都可写,因此应用程序和存储过程都可以写入它。

然而,现在我开始使用 virtualenv 并将一些 .pth 文件添加到我的 ~/.virtualenvs/virt_env/lib/python2.7/site-packages/ 文件夹中,这些文件将我的模块的路径添加到 Python 路径中。

存储过程执行时,用户postgres和我不在同一个虚拟环境,所以存储过程找不到我的模块。我可以在global PostgreSQL environment 中修改PYTHONPATH,但是每次切换虚拟环境时我都必须更改它——这有点违背 virtualenv 的目的......

如何扩展存储过程的 Python 路径?

更新

已询问similar question,解决方案是修改 Postgres 中的 PYTHONPATH 环境变量;但是,似乎there is no standard way to specify environment variables for PostgreSQL;至少,它在 Mac OSX 上不是一个可行的解决方案。

【问题讨论】:

    标签: python postgresql stored-procedures virtualenv plpython


    【解决方案1】:

    事实证明,有一种方法可以做到这一点。从 1.6 或更高版本开始,virtualenv 带有一个脚本activate_this.py,可用于设置现有解释器以访问该特定 virtualenv。

    exec(open('/Some/VirtualEnv/Directory/myvirtualenv/bin/activate_this.py').read(), 
    dict(__file__='/Some/VirtualEnv/Directory/myvirtualenv/bin/activate_this.py'))
    

    并且作为一个完全实现的plpython函数:

    CREATE OR REPLACE FUNCTION workon(venv text)
      RETURNS void AS
    $BODY$
        import os
        import sys
    
        if sys.platform in ('win32', 'win64', 'cygwin'):
            activate_this = os.path.join(venv, 'Scripts', 'activate_this.py')
        else:
            if not os.environ.has_key('PATH'):
                import subprocess
                p=subprocess.Popen('echo -n $PATH', stdout=subprocess.PIPE, shell=True)
                (mypath,err) = p.communicate()
                os.environ['PATH'] = mypath
    
            activate_this = os.path.join(venv, 'bin', 'activate_this.py')
    
        exec(open(activate_this).read(), dict(__file__=activate_this))
    $BODY$
    LANGUAGE plpythonu VOLATILE
    

    (需要额外的 PATH mungery,因为默认情况下 PATH 在 plpython os.environ 中不可用 - activate_this.py 有一个fix checked in,它应该与下一个版本(应该是 1.11.7 或 1.12)一起滚动

    (主要取自https://gist.github.com/dmckeone/69334e2d8b27f586414a

    【讨论】:

    • 我不确定这个 virtualenv 路径是否在多个 plpython 调用中保持活动状态,因为解释器在每次调用时都是新的。我想你假设我们在一开始就从所有 plpython 方法调用 workon() ?
    • 实际上,在一个会话(数据库连接)中,所有 plpython 函数共享一个解释器,尽管它们获得了一个新的执行状态(除了全局 GD 数据共享字典)——你不需要为每个查询。不要多次调用,sys.path会不断增长
    【解决方案2】:

    通常我会说这不是一个好主意,但您可以关注this question

    您可以做的是在不同的环境中运行多个 PostgreSQL 实例,以允许各种 PYTHONPATH 设置。

    【讨论】:

      猜你喜欢
      • 2017-04-13
      • 1970-01-01
      • 2016-01-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-06-09
      相关资源
      最近更新 更多