处理SQLAlchemy会话的WSGI应用程序中间件
我的WSGI应用程序使用SQLAlchemy。我想在请求启动时启动会话,如果会话脏且请求处理成功完成,则提交会话,否则进行回滚。因此,我需要实现Django的处理SQLAlchemy会话的WSGI应用程序中间件,sqlalchemy,wsgi,middleware,Sqlalchemy,Wsgi,Middleware,我的WSGI应用程序使用SQLAlchemy。我想在请求启动时启动会话,如果会话脏且请求处理成功完成,则提交会话,否则进行回滚。因此,我需要实现Django的事务中间件的行为 因此,我想我应该创建WSGI中间件并制作以下内容: 在预处理时创建DB会话并将其添加到环境中 从environ获取数据库会话,并在后期处理时调用commit(),如果没有发生错误 从environ获取数据库会话,并在后期处理时调用rollback(),如果出现一些错误 第一步对我来说是显而易见的: class DbSess
事务中间件的行为
因此,我想我应该创建WSGI中间件并制作以下内容:
在预处理时创建DB会话并将其添加到环境中
从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步-不是。我找到了后处理任务的名称:
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()
它包含以下评论:
请注意,\uuuuuu call\uuuu
函数是一个Python生成器,这是此类“后处理”任务的典型例子
请你澄清一下它是如何工作的,我怎样才能同样地解决我的问题
谢谢,
Boris.对于步骤1,我使用SQLAlchemy:
它们为每个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()
如您所见,我在会话上启动嵌套事务,以便能够回滚视图中已提交的查询。我是否可以安全地在self.app中使用db.get\u session()
?例如,像这样-db.get_session().query(…)
?或者线程本地存储有问题吗?
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()