Sqlalchemy: Using decorator to provide thread-safe session for multiple functions Sqlalchemy: Using decorator to provide thread-safe session for multiple functions multithreading multithreading

Sqlalchemy: Using decorator to provide thread-safe session for multiple functions


I think it here would make sense to use a scoped_session, maybe like this:

session_factory = sessionmaker(bind=some_engine)Session = scoped_session(session_factory)def dbconnect(func):    def inner(*args, **kwargs):        session = Session()  # (this is now a scoped session)        try:            func(*args, **kwargs) # No need to pass session explicitly            session.commit()        except:            session.rollback()            raise        finally:            Session.remove()  # NOTE: *remove* rather than *close* here    return inner@dbconnectdef some_function(some, arguments):    session = Session()    # 'session' is  now a handle to the *same* session as in the decorator    session.query(...) # no commit, close, rollback requiredsome_function("many", "different_arguments") #session is not required, since provided by decorator

(Warning: Untested)


Decorators that add arguments are interesting but potentially tricky. The argument list as defined is now out of step with what callers will actually use. If you explicitly pass session=something to this it will raise an exception (though you could check for that in the decorator)

You'll also want to add at least a functools.wraps (granted, this is short sample code).

Transactions are a good use case for context managers. See What's the recommended scoped_session usage pattern in a multithreaded sqlalchemy webapp? for an idea on that.