使用Django的AppEngine应用程序无法加载
Django总是让我们的应用崩溃。部署后,应用运行得很好,但一旦初始实例重启或关闭,它常常无法启动,出现类似下面的错误:
Traceback (most recent call last): File "/base/data/home/runtimes/python27/python27_lib/versions/1/google/appengine/runtime/wsgi.py", line 266, in Handle
result = handler(dict(self._environ), self._StartResponse)
File "/base/data/home/runtimes/python27/python27_lib/versions/third_party/django-1.5/django/core/handlers/wsgi.py", line 236, in call
self.load_middleware()
File "/base/data/home/runtimes/python27/python27_lib/versions/third_party/django-1.5/django/core/handlers/base.py", line 53, in load_middleware
raise exceptions.ImproperlyConfigured('Error importing middleware %s: "%s"' % (mw_module, e))
ImproperlyConfigured: Error importing middleware myfolder.middleware: "No module named myfolder.middleware"
我们的文件结构大致是这样的:
|- app.yaml
|- _ _ init _ _.py
|- settings.py
|- myfolder |
| |- _ _ init _ _.py
| |- middleware.py
| |- ...
|-...
|
我们的app.yaml文件内容如下:
application: XXXXX
module: app
version: master
runtime: python27
api_version: 1
threadsafe: true
handlers: - url: /api/(login|logout|passwd|master.|banners.) script: app.handler secure: always ...
builtins: - django_wsgi: on
libraries: - name: django version: 1.5
env_variables: DJANGO_SETTINGS_MODULE: 'settings'
我们的应用有两个模块,它们都表现出这种情况(配置相似)。有时候这些模块能持续运行整整一天,然后又崩溃。它们加载失败后,所有后续请求都会出现同样的错误。再部署一次总是能暂时解决这个问题。
我们使用的是普通的Django和CloudSql。在开发服务器上无法重现这个问题。部署后,两个模块中的一切都运行得很好。所有的中间件、ndb、memcache、cloudsql、taskqueue等等,包括“myfolder”里的所有模块和其他复制过来的库。
我们尝试解决这个问题的方法都没有成功:
- 我们尝试使用appengine_config.py强制Django重新加载设置,代码是:from django.conf import settings\nsettings._target = None\n
- 最开始我们在“myfolder”里有共享设置,并在根目录的settings.py中用“from myfolder.shared_settings import *”导入,但Django也无法加载模块myfolder.shared_settings(类似的问题)
- 使用自定义的mysettings.py,并在app.yaml或Python中定义DJANGO_SETTINGS_MODULE
系统还没有上线,但很快就会,我们的选择越来越少。
其他类似失败配置的痕迹:
Traceback (most recent call last):
File "/base/data/home/runtimes/python27/python27_lib/versions/1/google/appengine/runtime/wsgi.py", line 266, in Handle
result = handler(dict(self._environ), self._StartResponse)
File "/base/data/home/runtimes/python27/python27_lib/versions/third_party/django-1.5/django/core/handlers/wsgi.py", line 236, in __call__
self.load_middleware()
File "/base/data/home/runtimes/python27/python27_lib/versions/third_party/django-1.5/django/core/handlers/base.py", line 45, in load_middleware
for middleware_path in settings.MIDDLEWARE_CLASSES:
File "/base/data/home/runtimes/python27/python27_lib/versions/third_party/django-1.5/django/conf/__init__.py", line 53, in __getattr__
self._setup(name)
File "/base/data/home/runtimes/python27/python27_lib/versions/third_party/django-1.5/django/conf/__init__.py", line 48, in _setup
self._wrapped = Settings(settings_module)
File "/base/data/home/runtimes/python27/python27_lib/versions/third_party/django-1.5/django/conf/__init__.py", line 134, in __init__
raise ImportError("Could not import settings '%s' (Is it on sys.path?): %s" % (self.SETTINGS_MODULE, e))
ImportError: Could not import settings 'settings' (Is it on sys.path?): No module named myfolder.settings
Traceback (most recent call last):
File "/base/data/home/runtimes/python27/python27_lib/versions/1/google/appengine/runtime/wsgi.py", line 239, in Handle
handler = _config_handle.add_wsgi_middleware(self._LoadHandler())
File "/base/data/home/runtimes/python27/python27_lib/versions/1/google/appengine/api/lib_config.py", line 353, in __getattr__
self._update_configs()
File "/base/data/home/runtimes/python27/python27_lib/versions/1/google/appengine/api/lib_config.py", line 289, in _update_configs
self._registry.initialize()
File "/base/data/home/runtimes/python27/python27_lib/versions/1/google/appengine/api/lib_config.py", line 164, in initialize
import_func(self._modname)
File "/base/data/home/apps/s~blue-myapp/app:master.375531077560785947/appengine_config.py", line 17, in
settings._target = None
File "/base/data/home/runtimes/python27/python27_lib/versions/third_party/django-1.5/django/utils/functional.py", line 227, in __setattr__
self._setup()
File "/base/data/home/runtimes/python27/python27_lib/versions/third_party/django-1.5/django/conf/__init__.py", line 48, in _setup
self._wrapped = Settings(settings_module)
File "/base/data/home/runtimes/python27/python27_lib/versions/third_party/django-1.5/django/conf/__init__.py", line 134, in __init__
raise ImportError("Could not import settings '%s' (Is it on sys.path?): %s" % (self.SETTINGS_MODULE, e))
ImportError: Could not import settings 'settings' (Is it on sys.path?): No module named myfolder.settings
这是我们当前的appengine_config.py:
import sys
import logging
logging.debug(",\n".join(sys.path))
# Since Google App Engine's webapp framework uses Django templates, Django will half-initialize when webapp is loaded.
# This causes the initialization of the rest of Django's setting to be skipped. If you are getting this error, you need
# to explicitly force Django to reload your settings:
from django.conf import settings
settings._target = None
从appengine_config.py记录sys.path时,成功启动实例和失败启动实例之间没有变化(当然,XXXXXXXXXXX那部分除外):
/base/data/home/apps/s~blue-persomi/app:master.3759720XXXXXXXXXXX,
/base/data/home/runtimes/python27/python27_dist/lib/python27.zip,
/base/data/home/runtimes/python27/python27_dist/lib/python2.7,
/base/data/home/runtimes/python27/python27_dist/lib/python2.7/plat-linux2,
/base/data/home/runtimes/python27/python27_dist/lib/python2.7/lib-tk,
/base/data/home/runtimes/python27/python27_dist/lib/python2.7/lib-old,
/base/data/home/runtimes/python27/python27_dist/lib/python2.7/lib-dynload,
/base/data/home/runtimes/python27/python27_dist/lib/python2.7/site-packages,
/base/data/home/runtimes/python27/python27_lib/versions/1,
/base/data/home/runtimes/python27/python27_lib/versions/third_party/MySQLdb-1.2.4b4,
/base/data/home/runtimes/python27/python27_lib/versions/third_party/django-1.5,
/base/data/home/runtimes/python27/python27_lib/versions/third_party/protorpc-1.0,
/base/data/home/runtimes/python27/python27_lib/versions/third_party/webapp2-2.5.2,
/base/data/home/runtimes/python27/python27_lib/versions/third_party/webob-1.1.1,
/base/data/home/runtimes/python27/python27_lib/versions/third_party/yaml-3.10
2 个回答
在你的 app.yaml 文件中添加以下几行:
libraries:
- name: MySQLdb
version: "latest"
具体的说明可以在这里找到:
https://cloud.google.com/appengine/docs/python/cloud-sql/
理想情况下,这些内容应该在 GCM DJANGO 的指南中有说明。这样我就能节省很多时间了。
Praveen
看起来这是个路径相关的问题,就像大家在你提问的评论里提到的那样。
一个可能的简单解决办法是手动把所有东西都加到你的路径里 - 可以看看这里的最佳答案:如何在 Google App Engine 中导入模块? 至少,这样可以帮助你把问题缩小到路径相关的范围。
文档里是这么说的:https://developers.google.com/appengine/docs/python/
Python 模块的包含路径包括你应用的根目录(也就是包含 app.yaml 文件的目录)。你在应用根目录下创建的模块可以通过根目录的路径来访问。别忘了在子目录里创建 init.py 文件,这样 Python 才会把子目录识别为包。
所以根据我看到的,因为你提问中的所有内容都在 app.yaml 文件的同级或下级,路径应该已经是正确的。
- 仔细检查一下你的
__init__.py
文件是否都在正确的位置,并且拼写正确。 - 尝试删除所有的
*.pyc
文件,然后让它们重新生成。 - 尝试从容器的文件夹名称
FOLDER_CONTAINING_YAML.myfolder.middleware
中导入。