Note: This article is not about using SQLAlchemy and Tornado to do asynchronous calls to your database. It is about making sure each request uses the correct session even if it does async calls to other services.
Session management with SQLAlchemy and Tornado is a little bit tricky if you are doing asynchronous calls. You have to be careful to make sure your request is using the same session before and after an async call. The recommended way to do this is to associate a session with the request itself, but this is not feasible if you are using declarative_base. I got around this issue by making my own scoping function and patching tornado.
The scoping function is extremely simple. The get method it defines is used by scoped_session to determine the correct session object to provide from its registry. The handlers and patches will use to the set method to set the correct session scope.
We create a base handler that sets the correct scope using the scope object created in database.py.
Finally, we do a little bit of monkey patching so the correct scope will be maintained before and after async calls using tornado.gen
With all this in place, we can safely have declarative base models and commit sessions whenever we want.