Reputation: 61
Problem: Flask app.teardown_appcontext is not being called when DEBUG is false. Flask's app.teardown_request works just fine.
Background: This problem was first discovered because of the error (2013, 'lost connection to mysql server during query') which was only happening when DEBUG = False
After looking into this further, I realized that this was because the session was not being removed properly in flask_sqlalchemy.
def create_app(config_obj):
app = Flask(__name__)
env = Environments(app)
env.from_object(config_obj)
# init extensions
SetupLogs(app)
db.init_app(app)
api.init_app(app)
CORS(app)
# This gets called after each request
@app.teardown_request
def teardown_request(response_or_exc):
db.session.remove()
# This never gets called after requests only when DEBUG = False!
@app.teardown_appcontext
def teardown_appcontext(response_or_exc):
db.session.remove()
return app
app = create_app('config')
manager = Manager(app)
migrate = Migrate(app, db)
...
Upvotes: 3
Views: 7126
Reputation: 61
I finally found the problem and it was actually a side effect of using Flask-Script with Flask-SqlAlchemy.
If SQLAlchemy is instantiated with init_app, then app.app_context().push() must be used if performing DB operations outside of the scoped session(made in the request). More Details But if an app context is pushed, then it must be closed manually otherwise it will never be torn down and therefore never trigger the teardown_appcontext.
Flask-Script runs commands inside a flask test context which i believe kept the app context alive.
Upvotes: 3