Pyramid bootstrap后Session执行查询报NoTransaction异常的解决咨询
解决Pyramid后台脚本中Session的NoTransaction异常问题
这个问题我之前处理过,核心原因是你通过bootstrap获取的请求对象,并没有像视图请求那样被Pyramid的事务中间件自动初始化顶层事务——而begin_nested()必须依赖一个已存在的顶层事务才能工作,这就是为什么你会触发NoTransaction异常。
下面是两种和视图行为一致的正确实现方式:
方法1:使用transaction模块管理顶层事务(推荐)
Pyramid的SQLAlchemy集成默认和transaction库深度绑定,视图里的事务就是由它自动管理的。在脚本里我们可以手动调用它来模拟视图的事务环境:
from pyramid.plaster import bootstrap import transaction import sys with bootstrap(sys.argv[1]) as env: dbsession = env['request'].dbsession # 启动顶层事务,和视图中的事务上下文一致 with transaction.manager: # 这里可以直接执行查询或写操作,事务会自动提交(如果是写操作) res = dbsession.execute('''SELECT ....''') # 处理查询结果 for row in res: print(row)
方法2:直接用Session开启顶层事务
如果你更倾向于直接操作Session的事务API,需要先开启顶层事务,再使用嵌套事务(如果需要):
from pyramid.plaster import bootstrap import sys with bootstrap(sys.argv[1]) as env: dbsession = env['request'].dbsession # 先启动顶层事务,这是嵌套事务的前提 with dbsession.begin(): # 现在可以正常使用嵌套事务了 with dbsession.begin_nested(): res = dbsession.execute('''SELECT ....''') ...
为什么你的原代码会报错?
你直接调用dbsession.begin_nested()时,Session并没有任何活跃的顶层事务——而嵌套事务是依附于顶层事务存在的。在视图请求中,Pyramid的tweens(比如事务tween)会自动帮你启动顶层事务,所以嵌套事务能正常工作,但脚本环境中需要我们手动完成这一步。
内容的提问来源于stack exchange,提问作者viraptor
相关产品推荐
相关产品推荐

