我想在共享主机上部署一个烧瓶应用程序。它使用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 FAQ上有一个注释:
如果消息报告未定义的符号: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?
答案 0 :(得分:0)
如果你有psycopg2包含的C代码,那么简单地复制python文件是行不通的。作为解决方法,您可以使用pure-python pg8000或:
virtualenv env
创建virtualenv。env/bin/pip install psycopg2
。env/bin/pip freeze > requirements.txt
requirements.txt
复制到部署服务器,如果您正在使用版本控制,则还应检查此文件。pip install -r requirements.txt
。./env/bin/python foo.py
希望有所帮助。如果您还有其他问题,请发表评论。