在Flask-SQLAlchemy和Celery的celery任务中正确管理postgresql连接

时间:2016-06-14 01:51:36

标签: python postgresql flask celery flask-sqlalchemy

我正在使用Flask-SQLAlchemy,Celery和uWSGI。

我知道Flask-SQLAlchemy会自动为您管理会话。我不确定这如何与Celery工作者一起工作,但似乎当我第二次运行任务时,我收到以下错误:DatabaseError:(psycopg2.DatabaseError)服务器意外关闭了连接。

以下是我创建应用程序上下文和芹菜任务的方法:

def make_celery(app):
    celery = Celery(
        app.import_name,
        backend=app.config['CELERY_BACKEND'],
        broker=app.config['CELERY_BROKER_URL'],
    )
    celery.conf.update(app.config)
    TaskBase = celery.Task

    class ContextTask(TaskBase):
        abstract = True
        def __call__(self, *args, **kwargs):
            with app.app_context():
                return TaskBase.__call__(self, *args, **kwargs)
    celery.Task = ContextTask
    return celery

似乎工作者可能正在使用相同的数据库连接,并且在任务完成后,该连接未得到补充?

可能与following question

有关

我不确定如何正确设置工人或芹菜,以便他们使用新的数据库连接。

1 个答案:

答案 0 :(得分:1)

好。我想通了,对于使用应用程序上下文的每个进程,您必须使用新的应用程序上下文。之前,在我的app/__init__.py中,我只是在全局范围内创建应用程序:

from flask import Flask
app = Flask(__name__)

然后我将我的应用更改为使用this pattern

中的create_app

现在,我的tasks.py看起来像这样:

from myapp import create_app
from celery import Celery
def make_celery(app=None):
    app = app or create_app()
    celery = Celery(
        app.import_name,
        backend=app.config['CELERY_BACKEND'],
        broker=app.config['CELERY_BROKER_URL'],
    )
    celery.conf.update(app.config)
    TaskBase = celery.Task

    class ContextTask(TaskBase):
        abstract = True
        def __call__(self, *args, **kwargs):
            with app.app_context():
                return TaskBase.__call__(self, *args, **kwargs)
    celery.Task = ContextTask
    return celery

celery = make_celery()

确保在create_app中调用db.init_app(app)。