Heroku上的Flask和Celery:sqlalchemy.exc.DatabaseError:(psycopg2.DatabaseError)SSL错误:解密失败或错误记录mac

时间:2017-07-20 13:04:07

标签: python heroku flask celery flask-sqlalchemy

我正在尝试在heroku上部署一个使用Celery中的后台任务的烧瓶应用程序。我已经实现了application factory pattern,以便芹菜进程不会被烧瓶app的任何一个实例绑定。

这在本地工作,我还没有看到错误。但是当部署到heroku时,总是会出现相同的结果:芹菜任务(我只使用一个)在第一次运行时成功,但任何后续芹菜调用该任务都失败了sqlalchemy.exc.DatabaseError: (psycopg2.DatabaseError) SSL error: decryption failed or bad record mac。如果我重新开始芹菜工作,那么循环就会继续。

multiple issues显示相同的error,但都没有指定正确的解决方案。我最初认为实现应用程序工厂模式会阻止此错误显示,但它并不存在。

app/__init__.py中,我创建了芹菜和数据库对象:

celery = Celery(__name__, broker=Config.CELERY_BROKER_URL)
db = SQLAlchemy()

def create_app(config_name):
    app = Flask(__name__)
    app.config.from_object(config[config_name])

    db.init_app(app)
    return app

我的flask_celery.py文件会创建实际的Flask应用对象:

import os
from app import celery, create_app

app = create_app(os.getenv('FLASK_CONFIG', 'default'))
app.app_context().push()

我用这个命令开始芹菜: celery worker -A app.flask_celery.celery --loglevel=info

这就是实际芹菜任务的样子:

@celery.task()
def task_process_stuff(stuff_id):
    stuff = Stuff.query.get(stuff_id)
    stuff.processed = True
    db.session.add(stuff)
    db.session.commit()
    return stuff

由以下人员调用:

task_process_stuff.apply_async(args=[stuff.id], countdown=10)

图书馆版本

  • 烧瓶0.12.2
  • SQLAlchemy 1.1.11
  • Flask-SQLAlchemy 2.2
  • Celery 4.0.2

1 个答案:

答案 0 :(得分:5)

解决方案是在任务开始时添加db.engine.dispose(),在任何工作开始之前处理所有数据库连接:

@celery.task()
def task_process_stuff(stuff_id):
    db.engine.dispose()
    stuff = Stuff.query.get(stuff_id)
    stuff.processed = True
    db.session.commit()
    return stuff

由于我需要在所有任务中使用此功能,因此我将其添加到task_prerun

@task_prerun.connect
def on_task_init(*args, **kwargs):
    db.engine.dispose()