Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/video/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
处理SQLAlchemy会话的WSGI应用程序中间件_Sqlalchemy_Wsgi_Middleware - Fatal编程技术网

处理SQLAlchemy会话的WSGI应用程序中间件

处理SQLAlchemy会话的WSGI应用程序中间件,sqlalchemy,wsgi,middleware,Sqlalchemy,Wsgi,Middleware,我的WSGI应用程序使用SQLAlchemy。我想在请求启动时启动会话,如果会话脏且请求处理成功完成,则提交会话,否则进行回滚。因此,我需要实现Django的事务中间件的行为 因此,我想我应该创建WSGI中间件并制作以下内容: 在预处理时创建DB会话并将其添加到环境中 从environ获取数据库会话,并在后期处理时调用commit(),如果没有发生错误 从environ获取数据库会话,并在后期处理时调用rollback(),如果出现一些错误 第一步对我来说是显而易见的: class DbSess

我的WSGI应用程序使用SQLAlchemy。我想在请求启动时启动会话,如果会话脏且请求处理成功完成,则提交会话,否则进行回滚。因此,我需要实现Django的
事务中间件的行为

因此,我想我应该创建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()