ImportError: No module named 'xxx'的另外一种原因

今天遇到了一个关于Python的ImportError: No module named 'xxx'问题,其中也算是一些经验总结,特记录如下。

    问题的场景大致是这样的:在django中我新建了一个名为sitesetting的app,这个app不是通过django的python manage.py startapp sitesetting命令来新建的,而是我手动mkdir sitesetting命令新建的。然后用nginx+uwsgi启动,访问sitesetting这个app就会出现出现出现ImportError: No module named 'sitesetting'的错误。
    看到这个错误首先想到的是sitesetting目录下面没有_init_.py文件,看了一下sitesetting却是有_init_.py文件的。
    接着我又检查了一下pythonpath中是包含了django的主目录的,也就是说Python的查找路径是没有问题的。
    此时我就有点纳闷了,我又对照了一遍sitesetting目录下面的文件列表和其它正常的app的文件列表,没有发现问题。检查了一下settings.py中的配置都没有发现问题。
    接着我用python manage.py runserver 0:8080方式起来了一个服务,竟然没有出现ImportError的错误,此时头脑已经有点迷糊了,没有去深思这个现象。
    我想要不用python manage.py startapp sitesetting命令来新建这个app看看会不会报错吧,mv sitesetting sitesetting2重命名了sitesetting app,用python manage.py startapp sitesetting命令新建了sitesetting app。接着把nginx重启一下,发现没有报错了。难道startapp这种方式会在某一个地方增加一些配置?我查了一遍django的文档,没有发现startapp这种方式有什么隐藏的功能除了新建目录和文件外。想哭……
    到现在能验证的步骤基本都验证完了,脑子也越来越迷糊了。不行,我得休息休息一会了。
    喝杯水,把整个验证过程在脑子中过了一遍,发现有两个验证方法没有报错,这两个都没有什么特别的联系。此时,突然脑子突然灵光一现,难道是权限的问题?想到这一点线索,再结合这两个没有报错的方式我基本就断定了应该是权限导致了这个”诡异”的问题。
    我ls -l对比看了一下sitesetting(用startapp新建的)和sitesetting2(用mkdir新建的),发现一个owner:group是apache,一个是root,而且sitesetting2的权限是700,所以用nginx+uwsgi启动服务的时候apache用户是没有读权限的,所以最后也就报出了ImportError的错误。

drwxr-xr-x 2 apache apache 4.0K May 18 17:09 sitesetting

drwx------ 2 root   root   4.0K May 18 15:37 sitesetting2

    折腾了半天最后发现是这么一个原因导致的问题,事后回想了一下其实我很早以前也遇到过类似的问题,用manage.py的方式没有问题,用nginx+uwsgi就有问题,当时也是折腾了半天才发现原因。这次我总结了几点:
1. 凡是遇到manage.pynginx+uwsgi运行不一致的情况,一定要优先考虑权限的问题。
2. 测试的时候不要认为manage.py自测没问题了就OK了,一定要模拟真正的线上环境来测试。
3. Python的ImportError除了前面我们列举的几个可能原因以外再加一个py文件权限的原因。
4. 遇到这种百思不得其解的问题一定不要钻牛角尖,适当的放松思考。

©️2020 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页