I have a python application which has lots of small database access functions, using sqlalchemy. I\'m trying to avoid having lots of boilerplate session handling code around
morphyn's suggestion to use a context manager is good. You could make such a context manager by applying the contextlib.contextmanager
decorator to a function very much like your first get_ticket_history
, replacing the code between try and except with a yield
statement and renaming it, say, transaction
. PEP 343 has a near-identical example of that name.
Then, use that context manager with the with statement to reimplement get_ticket_history
. It looks like SQLAlchemy already provides that function, though, as method begin
:
http://docs.sqlalchemy.org/en/rel_0_8/orm/session.html#autocommit-mode
with
clausewith engine.begin() as connection:
r1 = connection.execute(table1.select())
connection.execute(table1.insert(), {"col1": 7, "col2": "this is some data"})
Old questions, but I still stumbled upon it so here is the relevant link from the docu: https://docs.sqlalchemy.org/en/13/core/connections.html
The SQLAlchemy docs present a possible way of doing this with context managers.
http://docs.sqlalchemy.org/en/latest/orm/session_basics.html#when-do-i-construct-a-session-when-do-i-commit-it-and-when-do-i-close-it
Copying the code snippet here for completeness:
from contextlib import contextmanager
@contextmanager
def session_scope():
"""Provide a transactional scope around a series of operations."""
session = Session()
try:
yield session
session.commit()
except:
session.rollback()
raise
finally:
session.close()
This session_scope
can be used cleanly without repeating the boiler plate now.
class ThingOne(object):
def go(self, session):
session.query(FooBar).update({"x": 5})
class ThingTwo(object):
def go(self, session):
session.query(Widget).update({"q": 18})
def run_my_program():
with session_scope() as session:
ThingOne().go(session)
ThingTwo().go(session)