sqlalchemy предлагает шаблон транзакций для сеансов:
# myapp.py
from contextlib import contextmanager
engine = create_engine('sqlite:////tmp/test.db')
Session = sessionmaker(bind=engine)
@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()
...
with session_scope() as session:
# do stuff
Кроме того, я заметил, что для веб-приложений следует использовать session_scope
:
# my_scoped_app.py
from sqlalchemy import create_engine
from sqlalchemy.orm import scoped_session, sessionmaker
from sqlalchemy.ext.declarative import declarative_base
engine = create_engine('sqlite:////tmp/test.db')
db_session = scoped_session(sessionmaker(bind=engine))
...
# Some app definition
...
@app.teardown_appcontext
def shutdown_session(exception=None):
db_session.remove()
Поскольку я хочу масштаб Flask за пределами одного потока, безопасно ли использовать первый шаблон? Другими словами, имеет ли значение, реализую ли я какой-нибудь класс, например
from myapp import session_scope()
class Foo(object):
def do_stuff(self, args):
with session_scope() as session:
do_more_stuff(session, args)
против
from my_scoped_app import db_session:
class Foo(object):
def do_stuff(self, args):
session = db_session()
do_more_stuff(session, args)
session.commit()
session.close()
Игнорирование различий в обработке исключений.