7

I'm struggling to make my Flask, SQLAlchemy (mysql) and Celery setup work properly when there are multiple celery workers with multiple threads involved that all query the same database.

The problem is that I cannot figure out how and where to apply required changes that give the flask application and each celery worker an isolated database object.

From my understanding, separate sessions are required to avoid nasty database errors such as incomplete transactions that block other database queries.

This is my current project structure

/flask_celery.py

from celery import Celery

def make_celery(app):
    celery = Celery(app.import_name, backend=app.config['CELERY_RESULT_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

/app.py

#!/usr/bin/env python

import config
from app import app

app.run(port=82,debug=True, host='0.0.0.0')
#app.run(debug=True)

app/__init.py__

from flask import Flask
from celery import Celery
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate
from flask_celery import make_celery

app = Flask(__name__)
app.config.from_object('config')
app.secret_key = app.config['SECRET_SESSION_KEY']

db = SQLAlchemy(app)
migrate = Migrate(app, db)

celery = make_celery(app)
1
  • what error have you got? flask_sqlalchemy should work fine with threads. Commented Sep 6, 2018 at 11:38

1 Answer 1

1

Maybe give SQLALCHEMY_BINDS a chance. It's a guideline about how to bind multiple databases.

I afraid there are still extra moves you should made.

  • I assume you have config.py to hold app configurations. Adding SQLALCHEMY_BINDS in Config class with values you prepared, which maybe several other databases' uri.
  • Handling model classes in models.py if file exists.
  • Managing your bind_key as argument somehow(sorry i don't make this detailed).
  • Dealing with bind_key argument to the right celery work...

I hope this may help you a little. And please let me know if you work this out, so I could edit this answer for people who have similar cases.

Sign up to request clarification or add additional context in comments.

2 Comments

Will the "binds" option work with multiple binds to the same database? The documentation explicitly refers to binds to different db backends/systems? Anyhow, thanks for your efforts. I haven't had the time to test what you suggest yet. Will be happy to award you the bounty, if this leads to a suitable solution. Might take another day or two though until I get to it. Unfortunately, the bounty will expire soon. Is there a way to extend the bounty time?
@Jabb Absolutely sure it’s okay multiple bind-key towards to the same db. But i am afraid i misunderstand your question. I thought you might need multiple databases as backends. Now i figure out all you need are just isolated db sessions. As @georgexsh mentioned in comment above, flask-sqlalchemy should work well with threads. You might work on multi-threads in Flask scope. I am sorry for not being helpful, so it’s totally okay without bounty.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.