【问题标题】:psycopg2 error if called via fcgi如果通过 fcgi 调用 psycopg2 错误
【发布时间】:2015-08-31 20:36:04
【问题描述】:

我想在共享主机上部署一个烧瓶应用程序。它使用 psycopg2 并通过 apache 作为 fcgi 应用程序通过 flipflop 部署。测试或手动调用时一切正常,即使在生产服务器上也是如此。这意味着我可以在生产服务器上执行以下操作:

$ source env/bin/activate
$ python myapp.py
>>> from myapp import Post
>>> Post.query.all()
[<Post1>, <Post2>, ...]

但是如果通过 apache 服务器通过 fcgi 访问(例如访问应该显示所有帖子的 mysite.com/all_posts),则 apache 会抛出 500 并记录以下错误:

ImportError: /home/syntonym/project/env/lib/python3.4/site-packages/psycopg2/_psycopg.cpython-34m.so: undefined symbol: lo_truncate64

psycopg2 常见问题解答对此有说明:

如果消息报告 undefined symbol: lo_truncate64 这意味着 Psycopg 是使用大型对象 64 位 API 支持构建的(即在编译时使用的 libpq 至少为 9.3),但在运行时发现了较旧的 libpq 动态库。

为了避免这个问题:

您可以使用: $ ldd /path/to/packages/psycopg2/_psycopg.so | grep libpq 查找运行时使用的 libpq 动态库是什么。

您可以通过在安装时使用相同版本的 pg_config 和在运行时使用 libpq 来避免此问题。

$ ldd /home/syntonym/project/env/lib/python3.4/site-packages/psycopg2/_psycopg.cpython-34m.so | grep libpq
libpq.so.5 => /package/host/localhost/postgresql-9.3/lib/libpq.so.5 (0x00007fc4f7b30000)
$ pg_config
LIBDIR = /package/host/localhost/postgresql-9.3.2-1/li2b

我还尝试使用LD_LIBRARY_PATH="/package/host/localhost/postgresql-9.3.2-1/lib" 编译 psycopg2。 ldd 显示了与 pg_config 完全相同的库,但同样的错误仍然存​​在。

fgci 脚本如下:

#!/home/syntonym/project/env/bin/python3.4

import sys
sys.path.insert(0, "/home/syntonym/project")
print(sys.path)

from flipflop import WSGIServer
from myapp import app

if __name__ == "__main__":
    WSGIServer(app).run()

我自己的文件 (myapp.py) 是通过 scp 复制的,我通过 pip (pip install flask, pip install sqlalchemy, pip install psycopg2, ...) 在虚拟环境中手动安装了依赖项。因为该应用程序在没有 apache/fcgi 的情况下工作,所以我认为 python 应用程序上的所有内容都设置正确。

Apache (2.2) 使用 mod_fcgid 和 suexec。难道是apache通过某些环境变量或其他东西强制使用不同的libpg.so?

【问题讨论】:

  • 如何将项目部署到远程?
  • @hd1 通过 scp 手动复制 python 文件。 apache 是全局安装的(2.2 版)并使用 mod_fcgid 和 suexec(这样 fcgi 脚本以用户权限执行)。我对 apache 或 fcgi 没有经验,所以如果我遗漏了重要信息,请告诉我。

标签: python apache postgresql flask sqlalchemy


【解决方案1】:

如果你有psycopg2 包含的C 代码,那么简单地复制python 文件是行不通的。作为解决方法,您可以使用纯 python pg8000 或:

  1. 使用virtualenv env 创建virtualenv
  2. 在虚拟环境中安装 psycopg2 -- env/bin/pip install psycopg2
  3. 生成 requirements.txt -- env/bin/pip freeze &gt; requirements.txt
  4. requirements.txt 复制到您的部署服务器,如果您使用版本控制,您也应该签入此文件。
  5. 在部署服务器上重复第 1 步,但输入 pip install -r requirements.txt 而不是第 2 步。
  6. 在 virtualenv 中执行您的 python 脚本./env/bin/python foo.py

希望对您有所帮助。如果您还有其他问题,请发表评论。

【讨论】:

  • 对不起,我说的不完整。我只通过 scp 复制了我的烧瓶应用程序,然后我用python -m venv env 创建了一个 virtualenv,然后我手动安装了我的要求(键入 source env/bin/activate pip install flask ... pip install psycopg2)。在那之后我得到了source of psycopg2并通过python setup.py makepython setup.py install(使用来自venv的python)实现了它。错误还是一样。
  • 这需要添加到您的问题中
【解决方案2】:

suexec 不携带任何环境变量。一个解决方案是制作另一个 fcgi 脚本并获取 bashrc:

#!/etc/bin/env bash
source path/to/home/.bashrc
exec real_fcgi_script

或手动插入 libpg 的路径(即在 python 中通过 environ)。

【讨论】:

    猜你喜欢
    • 2018-12-17
    • 2012-07-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-25
    • 2017-10-18
    相关资源
    最近更新 更多