【发布时间】:2016-02-19 20:10:45
【问题描述】:
我正在编写一个烧瓶应用程序,将内容流式传输给用户,并且我正在尝试在这种流式传输发生时操纵数据库。这是一些示例代码(简化):
def work_hard(obj):
yield 'About to do a lot of work...'
obj.status = do_a_lot_of_work_very_slowly()
yield obj.status
db.session.commit()
obj.more = more_slow_stuff()
yield obj.more
db.session.commit()
yield 'Hard work is done!'
@app.route('/log/<int:objid>/work_hard', methods=['POST'])
def perform_action(objid):
obj = MyModel.query.get(objid)
return Response(work_hard(obj), mimetype='text/html')
这段代码给出了错误Instance <MyModel at 0x7f5555f046a0> is not bound to a Session; attribute refresh operation cannot proceed,但如果我在perform_action() 中调用db.session.commit() 而不是work_hard(),它可以工作。同样,如果我尝试访问flask 的request 实例,它在perform_action() 中有效,但在work_hard() 中无效(它抱怨我试图在请求上下文之外访问请求)。
我假设这些都是因为work_hard() 在perform_action() 返回之后执行。是否有可能以某种方式延长请求上下文以包含work_hard()?到目前为止,我只是将单个值从 request 传递到 work_hard() 并且工作到一定程度,但现在我需要提交到数据库,我不知道如何在这里修复数据库会话。
我不能只从perform_action() 调用db.session.commit(),我确实需要能够在数据库中实时进行多次更新,因为输出正在流式传输到 HTTP 客户端。
如果事实证明这是不可能的,我的备份计划是从子进程流式输出,然后在子进程中我将从那里连接到数据库,但我更愿意在同一个内完成所有操作尽可能处理。
谢谢!
【问题讨论】:
标签: python-3.x flask sqlalchemy