How to use Flask-SQLAlchemy in a Celery task

前端 未结 4 1605
傲寒
傲寒 2020-12-12 09:55

I recently switch to Celery 3.0. Before that I was using Flask-Celery in order to integrate Celery with Flask. Although it had many issues like hiding some powerful Celery f

4条回答
  •  -上瘾入骨i
    2020-12-12 10:52

    I used Paul Gibbs' answer with two differences. Instead of task_postrun I used worker_process_init. And instead of .remove() I used db.session.expire_all().

    I'm not 100% sure, but from what I understand the way this works is when Celery creates a worker process, all inherited/shared db sessions will be expired, and SQLAlchemy will create new sessions on demand unique to that worker process.

    So far it seems to have fixed my problem. With Paul's solution, when one worker finished and removed the session, another worker using the same session was still running its query, so db.session.remove() closed the connection while it was being used, giving me a "Lost connection to MySQL server during query" exception.

    Thanks Paul for steering me in the right direction!

    Nevermind that didn't work. I ended up having an argument in my Flask app factory to not run db.init_app(app) if Celery was calling it. Instead the workers will call it after Celery forks them. I now see several connections in my MySQL processlist.

    from extensions import db
    from celery.signals import worker_process_init
    from flask import current_app
    
    @worker_process_init.connect
    def celery_worker_init_db(**_):
        db.init_app(current_app)
    

提交回复
热议问题