来自Heroku App的500回应

时间:2014-01-18 21:12:27

标签: python heroku flask

我最近部署了一个我正在向Heroku开发的小应用程序。一切都按预期工作,直到我更新代码以使用flask-sqlalchemy,sqlalchemy和Heroku的PostgreSQL。在我these instructions后,我更新了items()方法中的代码,用数据填充页面并使用数据库发布。现在每当我导航到项目页面时,我都会收到500响应。

我很确定这是我为了使用数据库而添加的代码,因为应用程序中的其他页面工作正常。它们的编码方式与项目页面最初使用字典而不是数据库完全相同。它也可以在我的本地机器上运行,而不是在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日志

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

2 个答案:

答案 0 :(得分:2)

来自here

  

Web服务器(运行Web站点)遇到意外情况   阻止它履行请求的条件   客户端(例如您的Web浏览器或我们的CheckUpDown机器人)   访问请求的URL。

     

这是Web服务器生成的“全能”错误。基本上   出了问题,但服务器不能更具体   关于它对客户端的响应中的错误情况。此外   将500错误通知回客户端,Web服务器应该   生成某种内部错误日志,提供更多细节   什么地方出了错。它取决于Web服务器站点的运营商   找到并分析这些日志。 (上次更新时间:2013年10月)

如果您对此感到满意,请设置flask app to debug并添加一些日志记录。 Heroku logs gather stdout from your app,只需登录except / try:的{​​{1}}块内的stdout即可。接下来,为代码添加一些错误处理,以便确定故障点。最后,添加一些except:级别的日志记录来解释当您不调查问题时可以关闭的内容。

以下是stdout的一些简单的Python日志配置示例:

INFO

答案 1 :(得分:1)

经过大量谷歌搜索后,我确定问题是未创建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)

我宁愿将模型放在单独的文件中。我已经尝试了一些方法来实现这一点,但它们都没有奏效。

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

heroku logs命令两次都告诉我db无法导入。

我打算将问题标记为已回答,因为它现在按照我想要的方式工作,并将打开另一个问题,看看我如何将类定义移动到另一个文件,并且仍然可以正常工作。