mod_wsgi:ImportError:没有名为“编码”的模块

Posted

技术标签:

【中文标题】mod_wsgi:ImportError:没有名为“编码”的模块【英文标题】:mod_wsgi: ImportError: No module named 'encodings' 【发布时间】:2014-08-21 03:11:23 【问题描述】:

我在 CentOS 6.5 上使用 Apache 2.2.15。我正在尝试使用 mod_wsgi 设置 Django 应用程序。 我使用的是虚拟环境,mod_wsgi 配置了--with-python=/path/to/virtualenv/bin/python3.4

我已将此添加到我的httpd.conf

WSGIPythonPath /srv/myproject:/path/to/virtualenv/lib/python3.4/site-packages
WSGIPythonHome /path/to/virtualenv
<VirtualHost *:80>
WSGIScriptAlias / /srv/myproject/myproject/wsgi.py
...
</VirtualHost>

wsgi.py,我添加了

sys.path.insert(1, "/path/to/virtualenv/lib/python3.4/site-packages")

问题是当我尝试在浏览器中打开应用程序时,它会无限加载。这是 Apache 错误日志:

Fatal Python error: Py_Initialize: Unable to get the locale encoding
ImportError: No module named 'encodings'
[Mon Jun 30 17:37:28 2014] [notice] child pid 19370 exit signal Aborted (6)
[Mon Jun 30 17:37:28 2014] [notice] child pid 19371 exit signal Aborted (6)
...
[Mon Jun 30 17:37:28 2014] [notice] child pid 19377 exit signal Aborted (6)
Fatal Python error: Py_Initialize: Unable to get the locale encoding
ImportError: No module named 'encodings'

有趣的是,无论是系统安装Python(2.6)还是虚拟环境版本(3.4),import encodings都能正常工作!我尝试使用来自the mod_wsgi CheckingYourInstallation page 的示例 WSGI 脚本来确认 Apache 正在使用哪个版本的 Python,但我得到了相同的 ImportError。

有人对下一步有什么建议吗?我已经搜索了文档,但我不知道从哪里开始。

【问题讨论】:

可能是访问权限问题。 apache 用户是否对您的 virtualenv 中的所有内容具有读取权限(包括目录和父目录的执行权限)? 是的,确实如此。即使将我的虚拟环境文件夹中的所有内容都设置为 777 也不起作用! 我在使用 CentOS 6.5 和 Apache 2.2.15 时遇到了同样的问题 - Py_Initialize 无法导入编码。当我编译 Python 3.4.1 时,它给了我一些关于 exec 前缀的警告。也许这些是相关的。如果您有解决方案,我很想知道。 我通过使用 virtualenv 而不是 pyvenv 解决了我的问题。事实证明,pyvenv 并没有像 encoding 那样对所有本地模块进行符号链接,但 virtualenv 做到了。 More information about pyvenv vs virtualenv for Python 3.4 【参考方案1】:

所以在我的朋友(IE:SysAdmins)的帮助下,我们昨晚弄明白了。我通过示例学习得最好,因此假设您使用 mod_wsgi 作为 Linux 组 apache 使用用户 Flipperpa 运行 Apache。假设您在 my_project/wsgi.py 中使用 wsgi.py 托管在 /home/my_project 中。

在顶层(ls -l /):

drwxr-xr-x.  47 root root  4096 Jul  9 09:43 home

在主目录中(ls -l /home):

drwxrwsr-x   7 flipper        apache 4096 Jul 29 10:22 my_project

这是关键。小写“s”表示设置了 apache 组的 setgid 位,并设置了执行位。最后的“x”当然意味着任何人都可以执行。

在树下检查您的权限;这对我们有用。

【讨论】:

这对我来说是个问题,与application 在同一目录中的python 文件没有被导入。更改了文件的权限,以便组和其他人可以读取并且确实如此。 我已经应用了您在此处提到的所有步骤,但仍然遇到相同的错误 您是否在启用 SELinux 的情况下运行 CentOS/RedHat?如果是这样,您还会看到在文件上设置安全上下文。【参考方案2】:

问题是由 SELinux 引起的。我所做的是:

将项目文件移至 /home/admin/myproject 按照 FlipperPA 的回答更改了权限 并且,我认为至关重要的是,使用setsebool -P httpd_enable_homedirs onhttpd_enable_homedirs SELinux 布尔值设置为on

CentOS wiki 上的 SELinux guide 非常有帮助。例如,要进行调试,您可以运行setenforce Permissive,这样 SELinux 不会强制执行其规则,但仍会写入日志。之后记得再setenforce Enforcing

【讨论】:

【参考方案3】:

在 Windows 上,我通过将 Python 安装的 Lib 目录直接放在 PYTHONPATH 上解决了这个问题。这是必要的,尽管如果你直接在同一个 shell 中运行 Python,它不需要这个来查找 encodings 包:

set PYTHONPATH=C:\WinPython-64bit-3.4.4.6Qt5\python-3.4.4.amd64\Lib;%PYTHONPATH%
c:\apache24\bin\httpd.exe

还要确保使用正确的 mod_wsgi 版本。我从Unofficial Binaries page 下载了我的,并选择它来匹配 Python(上面示例中的 64 位 3.4)。在对启动 Apache 的 .bat 文件进行上述更改后,我的网站可以正常使用 Python。

请注意,我的 Python 版本 WinPython 是通过解压缩安装并将其放在 C: 驱动器中来安装的。因此它没有以通常的 Windows 方式安装在注册表中,这应该最大限度地减少注册表交互考虑。

【讨论】:

这应该没有必要。这可能会为您解决问题,但不太可能解决真正的问题。你确定 mod_wsgi 甚至是从那个 Python 安装构建的吗?也有可能您的注册表项在安装 Python 后已损坏,或者如果使用 mod_wsgi 并且 Apache 作为服务运行,则没有为所有用户安装 Python。 WinPython 没有以通常的 Windows 方式安装:您只需将其解压缩后放入 C: 驱动器即可。 mod_wsgi 是从Unofficial Binaries page 下载的,并选择匹配 Python(上例中为 64 位 3.4)。修复后,该网站与 Python 一起正常工作。弄清楚它为什么在 Windows 上完成这项工作超出了我的 Windows 技能水平。

以上是关于mod_wsgi:ImportError:没有名为“编码”的模块的主要内容,如果未能解决你的问题,请参考以下文章

Django Apache 和 Virtualenv ImportError:没有名为站点的模块

Flask、mod_wsgi 和 Apache:ImportError

ImportError:没有名为 parse 的模块

ImportError:没有名为 django.core.wsgi 的模块

Django + mod_wsgi + apache:ImportError at / No module named djproj.urls

Python、Django mod_wsgi、virtualenv 错误:ImportError: No module named os(路径不正确)