我的WSGI应用程序使用SQLAlchemy。我想在请求启动时启动会话,如果它是脏的则提交它并且请求处理成功完成,否则进行回滚。所以,我需要实现Django的TransactionMiddleware
。
所以,我想我应该创建WSGI中间件并制作以下内容:
environ
。environ
获取数据库会话,如果没有发生错误,请在后处理时调用commit()
。environ
获取数据库会话,并在发布错误时调用rollback()
进行后处理。第一步对我来说很明显:
class DbSessionMiddleware:
def __init__(self, app):
self.app = app
def __call__(self, environ, start_response):
environ['db_session'] = create_session()
return self.app(environ, start_response)
第2步和第3步 - 不是。我找到了example后处理任务:
class Caseless:
def __init__(self, app):
self.app = app
def __call__(self, environ, start_response):
for chunk in self.app(environ, start_response):
yield chunk.lower()
它包含评论:
请注意,
__call__
函数是一个Python生成器,这对于这种“后处理”任务来说是典型的。
请您澄清它是如何运作的,我如何能够同样解决我的问题。
谢谢, 鲍里斯。
答案 0 :(得分:3)
对于第1步,我使用SQLAlchemy scoped sessions:
engine = create_engine(settings.DB_URL, echo=settings.DEBUG, client_encoding='utf8')
Base = declarative_base()
sm = sessionmaker(bind=engine)
get_session = scoped_session(sm)
它们为每个get_session()调用返回相同的线程本地会话。
现在步骤2和3如下:
class DbSessionMiddleware:
def __init__(self, app):
self.app = app
def __call__(self, environ, start_response):
try:
db.get_session().begin_nested()
return self.app(environ, start_response)
except BaseException:
db.get_session().rollback()
raise
finally:
db.get_session().commit()
如您所见,我在会话上启动嵌套事务,以便能够回滚已在视图中提交的查询。