500 Response From Heroku App



我最近部署了一个正在开发到Heroku的小应用程序。在我更新代码以利用Blask-Sqlalchemy,Sqlalchemy和Heroku的PostgreSQL之前,一切都按预期工作。遵循这些说明后,我在items()方法中更新了代码,以用数据填充页面并使用数据库发布。现在,每当我导航到项目页面时,我都会收到500响应。

我很确定,这是我添加的代码将DB用作应用程序中的其他页面。它们的编码方式与最初使用字典而不是数据库的项目页面完全相同。它在我的本地机器上也不在Heroku上运行良好。

项目():

from flask import Flask, render_template, request
from forms import *
from models import *
from sqlalchemy.orm import sessionmaker
from flask.ext.sqlalchemy import SQLAlchemy
import os

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = os.environ['DATABASE_URL']
app.secret_key = 'secret_shhhhh!@#$1234'
db = SQLAlchemy(app)
@app.route('/items', methods=['GET', 'POST'])
def items():
    form = ItemForm()
    item_list = db.session.query(Item).all()
    if request.method == 'GET':
        return render_template('items.html', form=form, item_list=item_list)
    else:
        if form.validate():
            new_item = Item(form.sku.data, form.title.data)
            db.session.add(new_item)
            db.session.commit()
            form.sku.data = ''
            form.title.data = ''
            item_list = db.session.query(Item).all()
            return render_template('items.html', form=form, item_list=item_list, item_added=True)
        else:
            return render_template('items.html', form=form, item_list=item_list, item_added=False)

@app.route('/shelves', methods=['GET', 'POST'])
def shelves():
    form = ShelfForm()
    if request.method == 'GET':
        return render_template('shelves.html', form=form, test_shelf_dict=test_shelf_dict)
    else:
        if form.validate():
            test_shelf_dict[form.name.data] = form.name.data
            form.name.data = ''
            return render_template('shelves.html', form=form, test_shelf_dict=test_shelf_dict, shelf_added=True)
        else:
            return render_template('shelves.html', form=form, test_shelf_dict=test_shelf_dict, shelf_added=False)

requirements.txt

Flask==0.10.1
Flask-SQLAlchemy==1.0
Flask-WTF==0.9.4
Jinja2==2.7.1
MarkupSafe==0.18
SQLAlchemy==0.9.1
WTForms==1.0.5
Werkzeug==0.9.4
argparse==1.2.1
gunicorn==18.0
itsdangerous==0.23
psycopg2==2.5.2
wsgiref==0.1.2

更新了Heroku Logs

2014-01-18T21:51:10.073395+00:00 app[web.1]:     self.wsgi = self.app.wsgi()
2014-01-18T21:51:10.073395+00:00 app[web.1]:   File "/app/.heroku/python/lib/python2.7/site-packages/gunicorn/workers/base.py", line 106, in init_process
2014-01-18T21:51:10.073395+00:00 app[web.1]: 2014-01-18 21:51:10 [7] [ERROR] Exception in worker process:
2014-01-18T21:51:10.073395+00:00 app[web.1]: Traceback (most recent call last):
2014-01-18T21:51:10.073395+00:00 app[web.1]:   File "/app/.heroku/python/lib/python2.7/site-packages/gunicorn/app/base.py", line 114, in wsgi
2014-01-18T21:51:10.073395+00:00 app[web.1]:   File "/app/.heroku/python/lib/python2.7/site-packages/gunicorn/arbiter.py", line 495, in spawn_worker
2014-01-18T21:51:10.073395+00:00 app[web.1]:     worker.init_process()
2014-01-18T21:51:10.073623+00:00 app[web.1]:     return util.import_app(self.app_uri)
2014-01-18T21:51:10.073395+00:00 app[web.1]:     self.callable = self.load()
2014-01-18T21:51:10.073395+00:00 app[web.1]:     return self.load_wsgiapp()
2014-01-18T21:51:10.073623+00:00 app[web.1]:   File "/app/.heroku/python/lib/python2.7/site-packages/gunicorn/app/wsgiapp.py", line 49, in load_wsgiapp
2014-01-18T21:51:10.073623+00:00 app[web.1]:   File "/app/flasktest.py", line 17
2014-01-18T21:51:10.073623+00:00 app[web.1]:     app.config[debug=True]
2014-01-18T21:51:10.073395+00:00 app[web.1]:   File "/app/.heroku/python/lib/python2.7/site-packages/gunicorn/app/wsgiapp.py", line 62, in load
2014-01-18T21:51:10.073623+00:00 app[web.1]:   File "/app/.heroku/python/lib/python2.7/site-packages/gunicorn/util.py", line 354, in import_app
2014-01-18T21:51:10.073781+00:00 app[web.1]:   File "/app/.heroku/python/lib/python2.7/site-packages/gunicorn/workers/base.py", line 106, in init_process
2014-01-18T21:51:10.073781+00:00 app[web.1]:     return self.load_wsgiapp()
2014-01-18T21:51:10.073781+00:00 app[web.1]:   File "/app/.heroku/python/lib/python2.7/site-packages/gunicorn/app/wsgiapp.py", line 49, in load_wsgiapp
2014-01-18T21:51:10.073781+00:00 app[web.1]:   File "/app/.heroku/python/lib/python2.7/site-packages/gunicorn/app/wsgiapp.py", line 62, in load
2014-01-18T21:51:10.073623+00:00 app[web.1]: Traceback (most recent call last):
2014-01-18T21:51:10.073623+00:00 app[web.1]:   File "/app/.heroku/python/lib/python2.7/site-packages/gunicorn/arbiter.py", line 495, in spawn_worker
2014-01-18T21:51:10.073623+00:00 app[web.1]:                     ^
2014-01-18T21:51:10.073623+00:00 app[web.1]:     __import__(module)
2014-01-18T21:51:10.073623+00:00 app[web.1]: SyntaxError: invalid syntax
2014-01-18T21:51:10.073781+00:00 app[web.1]:     worker.init_process()
2014-01-18T21:51:10.073781+00:00 app[web.1]:     self.wsgi = self.app.wsgi()
2014-01-18T21:51:10.074297+00:00 app[web.1]:   File "/app/flasktest.py", line 17
2014-01-18T21:51:10.074297+00:00 app[web.1]:                     ^
2014-01-18T21:51:10.073781+00:00 app[web.1]:     return util.import_app(self.app_uri)
2014-01-18T21:51:10.073781+00:00 app[web.1]:   File "/app/.heroku/python/lib/python2.7/site-packages/gunicorn/util.py", line 354, in import_app
2014-01-18T21:51:10.073781+00:00 app[web.1]:   File "/app/.heroku/python/lib/python2.7/site-packages/gunicorn/app/base.py", line 114, in wsgi
2014-01-18T21:51:10.074297+00:00 app[web.1]: SyntaxError: invalid syntax
2014-01-18T21:51:10.074297+00:00 app[web.1]:     __import__(module)
2014-01-18T21:51:10.073781+00:00 app[web.1]:     self.callable = self.load()
2014-01-18T21:51:10.074297+00:00 app[web.1]:     app.config[debug=True]
2014-01-18T21:51:10.074297+00:00 app[web.1]: 2014-01-18 21:51:10 [7] [INFO] Worker exiting (pid: 7)
2014-01-18T21:51:10.197186+00:00 app[web.1]: 2014-01-18 21:51:10 [2] [INFO] Reason: Worker failed to boot.
2014-01-18T21:51:10.197025+00:00 app[web.1]: 2014-01-18 21:51:10 [2] [INFO] Shutting down: Master
2014-01-18T21:51:11.464431+00:00 heroku[web.1]: State changed from starting to crashed
2014-01-18T21:51:11.448083+00:00 heroku[web.1]: Process exited with status 3
2014-01-18T21:51:18.281373+00:00 heroku[router]: at=error code=H10 desc="App crashed" method=GET path=/items host=glacial-spire-3650.herokuapp.com request_id=612d0d1e-4a04-46f0-b96f-5ddbdb420e78 fwd="24.164.177.131" dyno= connect= service= status=503 bytes=

更新:配置错误记录并正确调试后,我相信这是问题的根源:

2014-01-19T04:00:34.648038+00:00 app[web.1]: LINE 2: FROM item
2014-01-19T04:00:34.648038+00:00 app[web.1]: ERROR:flasktest:(ProgrammingError) relation "item" does not exist  # This line right here

这是我模型的代码,我相信错误消息是在我的模型中引用第一行:

class Item(Base):
    __tablename__ = 'item'  # I believe this is the relation that doesn't exist
    item_id = Column(Integer, primary_key=True, autoincrement=True)
    sku = Column(String(50), nullable=False, unique=True)
    title = Column(String(100), nullable=False)
    def __init__(self, sku, title):
        self.sku = sku
        self.title = title

从这里:

Web服务器(运行网站)遇到了出乎意料的阻止其满足要求的条件客户端(例如,您的Web浏览器或我们的检查机器人)访问请求的URL。

这是Web服务器生成的"接收器"错误。基本上某些问题出了问题,但是服务器不能更具体关于其对客户端的响应中的错误条件。此外要回到客户端的500个错误,Web服务器应生成某种内部错误日志,该日志提供了更多的详细信息什么地方出了错。它取决于Web服务器网站的运营商找到并分析这些日志。(上次更新:2013年10月)

如果您还可以,请将烧瓶应用程序设置为调试,并添加一些记录。Heroku Logs从您的应用程序中收集Stdout,因此只需在try:/except:except块内登录到stdout。接下来,在代码中添加一些错误处理,以便您可以确定故障点。最后,添加一些INFO-级记录以解释发生的事情,您可以在不调查问题时关闭。

这是一些简单的Python记录配置的示例:

import logging
import sys
# Defaults to stdout
logging.basicConfig(level=logging.INFO)
# get the logger for the current Python module
log = logging.getLogger(__name__)
try: 
    log.info('Start reading database')
    # do risky stuff
except:
    # http://docs.python.org/2/library/sys.html
    _, ex, _ = sys.exc_info()
    log.error(ex.message)

大量谷歌搜索后,我确定问题是未创建的item表。我已经解决了问题,但是这并不是我首选的方法。通过更改我的模型并将其移动到主文件,一切都按预期行为:

from flask import Flask, render_template, request
from forms import *
from models import Bin, Shelf, BinItem
from sqlalchemy.orm import sessionmaker
from flask.ext.sqlalchemy import SQLAlchemy
import os
import logging
import sys

logging.basicConfig(level=logging.INFO)
log = logging.getLogger(__name__)
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = os.environ['DATABASE_URL']
app.secret_key = 'secret_shhhhh!@#$1234'
db = SQLAlchemy(app)
class Item(db.Model):
    __tablename__ = 'item'
    item_id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    sku = db.Column(db.String(50), nullable=False, unique=True)
    title = db.Column(db.String(100), nullable=False)
    def __init__(self, sku, title):
        self.sku = sku
        self.title = title
@app.route('/items', methods=['GET', 'POST'])
def items():
    try:
        log.info('Start reading form DB')
        form = ItemForm()
        item_list = db.session.query(Item).all()
        if request.method == 'GET':
            return render_template('items.html', form=form, item_list=item_list)
        else:
            if form.validate():
                new_item = Item(form.sku.data, form.title.data)
                db.session.add(new_item)
                db.session.commit()
                form.sku.data = ''
                form.title.data = ''
                item_list = db.session.query(Item).all()
                return render_template('items.html', form=form, item_list=item_list, item_added=True)
            else:
                return render_template('items.html', form=form, item_list=item_list, item_added=False)
    except:
        _, ex, _ = sys.exc_info()
        log.error(ex.message)

我宁愿将模型放在单独的文件中。我已经尝试了一些事情来实现这一目标,但它们都没有起作用。

  • models文件中声明db =SQLAlchemy(app),修改Item类以匹配以上并将db导入到我的主文件中。
  • 修改Item类以匹配上述并将db从主文件导入到models

在两种情况下,heroku logs命令告诉我db无法导入。

我将标记这个问题是回答的,因为现在它正在按照我想要的方式工作,并将打开另一个问题,以查看如何将类定义移至另一个文件并仍然使所有内容都起作用。

最新更新