部署到 Heroku 时,如何在 Procfile 中使用 Gunicorn 导入自定义模块?

Gen*_*hta 3 python heroku importerror flask gunicorn

现在我正在将 Flask 应用程序部署到 Heroku,这是一个自定义表单模块。

\n\n

当我检查 heroku 日志时,它在尝试导入注册表单时收到导入错误。

\n\n
2016-03-16T18:40:08.254753+00:00 heroku[web.1]: State changed from crashed to starting\n2016-03-16T18:40:12.022731+00:00 heroku[web.1]: Starting process with command `gunicorn app.register:app`\n2016-03-16T18:40:14.912795+00:00 app[web.1]: [2016-03-16 18:40:14 +0000] [3] [INFO] Starting gunicorn 19.4.5\n2016-03-16T18:40:14.913529+00:00 app[web.1]: [2016-03-16 18:40:14 +0000] [3] [INFO] Listening at: http://0.0.0.0:39309 (3)\n2016-03-16T18:40:14.913654+00:00 app[web.1]: [2016-03-16 18:40:14 +0000] [3] [INFO] Using worker: sync\n2016-03-16T18:40:14.917468+00:00 app[web.1]: [2016-03-16 18:40:14 +0000] [7] [INFO] Booting worker with pid: 7\n2016-03-16T18:40:14.951783+00:00 app[web.1]: [2016-03-16 18:40:14 +0000] [8] [INFO] Booting worker with pid: 8\n2016-03-16T18:40:15.665966+00:00 heroku[web.1]: State changed from starting to up\n2016-03-16T18:40:15.568052+00:00 app[web.1]: [2016-03-16 18:40:15 +0000] [8] [ERROR] Exception in worker process:\n2016-03-16T18:40:15.568074+00:00 app[web.1]: Traceback (most recent call last):\n2016-03-16T18:40:15.568076+00:00 app[web.1]:   File "/app/.heroku/python/lib/python3.5/site-packages/gunicorn/arbiter.py", line 515, in spawn_worker\n2016-03-16T18:40:15.568076+00:00 app[web.1]:     worker.init_process()\n2016-03-16T18:40:15.568077+00:00 app[web.1]:   File "/app/.heroku/python/lib/python3.5/site-packages/gunicorn/workers/base.py", line 122, in init_process\n2016-03-16T18:40:15.568078+00:00 app[web.1]:     self.load_wsgi()\n2016-03-16T18:40:15.568078+00:00 app[web.1]:   File "/app/.heroku/python/lib/python3.5/site-packages/gunicorn/workers/base.py", line 130, in load_wsgi\n2016-03-16T18:40:15.568079+00:00 app[web.1]:     self.wsgi = self.app.wsgi()\n2016-03-16T18:40:15.568080+00:00 app[web.1]:   File "/app/.heroku/python/lib/python3.5/site-packages/gunicorn/app/base.py", line 67, in wsgi\n2016-03-16T18:40:15.568081+00:00 app[web.1]:     self.callable = self.load()\n2016-03-16T18:40:15.568081+00:00 app[web.1]:   File "/app/.heroku/python/lib/python3.5/site-packages/gunicorn/app/wsgiapp.py", line 65, in load\n2016-03-16T18:40:15.568082+00:00 app[web.1]:     return self.load_wsgiapp()\n2016-03-16T18:40:15.568083+00:00 app[web.1]:   File "/app/.heroku/python/lib/python3.5/site-packages/gunicorn/app/wsgiapp.py", line 52, in load_wsgiapp\n2016-03-16T18:40:15.568083+00:00 app[web.1]:     return util.import_app(self.app_uri)\n2016-03-16T18:40:15.568084+00:00 app[web.1]:   File "/app/.heroku/python/lib/python3.5/site-packages/gunicorn/util.py", line 357, in import_app\n2016-03-16T18:40:15.568085+00:00 app[web.1]:     __import__(module)\n2016-03-16T18:40:15.568086+00:00 app[web.1]:     from registration_form import RegistrationForm\n2016-03-16T18:40:15.568086+00:00 app[web.1]:   File "/app/app/register.py", line 2, in <module>\n2016-03-16T18:40:15.568087+00:00 app[web.1]: ImportError: No module named \'registration_form\'\n
Run Code Online (Sandbox Code Playgroud)\n\n

这就是目录的样子。

\n\n
app\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 register.py\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 registration_form.py\nProcfile\nrequirements.txt\nruntime.txt\nvirtual\n
Run Code Online (Sandbox Code Playgroud)\n\n

这在我的 Procfile 中。

\n\n
web: gunicorn app.register:app\n
Run Code Online (Sandbox Code Playgroud)\n\n

这是我的 app/register.py 文件

\n\n
from flask import Flask, render_template, request\nfrom registration_form import RegistrationForm\n\napp = Flask(__name__)\n\n@app.route(\'/register\', methods=[\'GET\', \'POST\'])\ndef register():\n    form = RegistrationForm(request.form)\n    #if request.method == \'POST\' and form.validate():\n    return render_template(\'register.html\', form=form)\n\nif __name__ == \'__main__\':\n    app.run(debug=True)\n
Run Code Online (Sandbox Code Playgroud)\n\n

这是我的 app/registration_form.py 文件

\n\n
from wtforms import Form, BooleanField, TextField, PasswordField, validators\n\nclass RegistrationForm(Form):\n    first_name = TextField(\'First Name\', [validators.Length(min=2, max=25)])\n    last_name = TextField(\'Last Name\', [validators.Length(min=4, max=35)])\n    email = TextField(\'Email\', [validators.Email()])\n    zip_code = TextField(\'Zip Code\', [validators.Length(min=4, max=35)])\n    accept_tos = BooleanField(\'I accept the TOS\', [validators.Required()])\n
Run Code Online (Sandbox Code Playgroud)\n\n

我应该在我的 Procfile 中添加什么来导入注册表单?当我在本地运行该应用程序时,它工作正常,所以我觉得它与 Gunicorn 的配置方式有关。

\n

dir*_*irn 5

Python 3.x 不支持您所采用的相对导入方式。您需要更新您的导入:

from .registration_form import RegistrationForm
Run Code Online (Sandbox Code Playgroud)

或者,您可以进行绝对导入:

from app.registration_form import RegistrationForm
Run Code Online (Sandbox Code Playgroud)