SQLAlchemy + Tornado:如何为SQLAlchemy的ScopedSession创建scopefunc?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SQLAlchemy + Tornado:如何为SQLAlchemy的ScopedSession创建scopefunc?相关的知识,希望对你有一定的参考价值。

使用龙卷风,我想创建一些中间件魔法,以确保我的SQLAlchemy会话得到正确关闭/清理,以便不会将对象从一个请求共享到下一个请求。诀窍是,由于我的一些龙卷风处理程序是异步的,我不能只为每个请求共享一个会话。

因此,我将尝试创建一个知道如何为每个请求创建新会话的ScopedSession。我需要做的就是为我的代码定义一个scopefunc,它可以将当前正在执行的请求转换为某种类型的唯一键,但是我似乎无法弄清楚如何在任何一个时间点获取当前请求(外部当前RequestHandler的范围,我的函数也没有访问权限)。

有什么我可以做的工作吗?

答案

您可能希望将Session与请求本身相关联(即,如果不方便,请不要使用scopedsession)。然后你可以说,request.session。仍然需要在开始/结束处设置钩子以进行设置/拆卸。

编辑:自定义范围功能

def get_current_tornado_request():
   # TODO: ask on the Tornado mailing list how
   # to acquire the request currently being invoked

Session = scoped_session(sessionmaker(), scopefunc=get_current_tornado_request)
另一答案

(这是对2011年问题的2017年答案)正如@Stefano Borini所指出的,在Tornado 4中最简单的方法就是让RequestHandler隐含地使用pass the session around。使用coroutine装饰器模式时,Tornado将跟踪处理程序实例状态:

import logging

_logger = logging.getLogger(__name__)

from sqlalchemy import create_engine, exc as sqla_exc
from sqlalchemy.orm import sessionmaker, exc as orm_exc

from tornado import gen
from tornado.web import RequestHandler

from my_models import SQLA_Class

Session = sessionmaker(bind=create_engine(...))

class BaseHandler(RequestHandler):

    @gen.coroutine
    def prepare():
        self.db_session = Session()

    def on_finish():
        self.db_session.close()

class MyHander(BaseHandler):

    @gen.coroutine
    def post():
        SQLA_Object = self.db_session.query(SQLA_Class)...
        SQLA_Object.attribute = ...

        try:
            db_session.commit()
        except sqla_exc.SQLAlchemyError:
            _logger.exception("Couldn't commit")
            db_session.rollback()

如果你真的需要异步引用declarative_base中的SQL Alchemy会话(我认为它反模式,因为它将模型过度耦合到应用程序),Amit Matani有一个非工作的例子here

以上是关于SQLAlchemy + Tornado:如何为SQLAlchemy的ScopedSession创建scopefunc?的主要内容,如果未能解决你的问题,请参考以下文章

从 python 使用 TSQL(SQL Server 上的 mssql)时,如何为 SQLAlchemy 自动生成 ORM 代码?

如何为Sqlalchemy中的各种模型编写一个通用的get_by_id()方法?

如何为pycharm配置龙卷风

SqlAlchemy + Tornado:在回滚无效事务之前无法重新连接

对Tornado异步操作Sqlalchemy方法的选定 不错

sqlalchemy在pythonweb中开发的使用(基于tornado的基础上)