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()方法?
SqlAlchemy + Tornado:在回滚无效事务之前无法重新连接