【问题标题】:Keeping SQLAlchemy session alive when streaming a Flask Response流式传输 Flask 响应时保持 SQLAlchemy 会话处于活动状态
【发布时间】:2018-10-23 20:39:06
【问题描述】:

我正在尝试从使用 Flask-SQLAlchemy 的 Flask 服务器将大型 CSV 流式传输到客户端。

配置应用时(使用工厂模式),每次请求后都会调用db.session.close()

@app.after_request
def close_connection(r):
    db.session.close()
    return r

到目前为止,此配置运行良好,因为所有请求都是短暂的。但是在流式传输响应时,SQLAlchemy 会话过早关闭,在调用生成器时抛出以下错误:

sqlalchemy.orm.exc.DetachedInstanceError: Parent instance <Question> is not bound to a Session; lazy load operation of attribute 'offered_answers' cannot proceed

伪代码:

@app.route('/export')
def export_data():
    answers = Answer.query.all()
    questions = Question.query.all()
    def generate():
        Iterate through answers questions and write out various relationships to csv

    response = Response(stream_with_context(generate()), mimetype='text/csv')
    return response

我已经尝试了使用/不使用stream_with_contextdef close_connection 中的全局标志的多种配置,以不自动关闭连接,但同样的错误仍然存​​在。

【问题讨论】:

    标签: python flask sqlalchemy flask-sqlalchemy


    【解决方案1】:

    @app.after_request 在调用流文件的生成器之前关闭数据库会话。

    解决方案是将db.session.close() 迁移到@app.teardown_request。实例化Response时也必须使用stream_with_context

    【讨论】:

    • Flask-sqlalchemy 已经完成了会话清理工作,因此您不需要自己实现:github.com/mitsuhiko/flask-sqlalchemy/blob/master/…
    • @codeape Flask-sqlalchemy 确实调用了session.remove()。但是,当我完全删除 @app.teardown_request 函数时,我的测试失败了。当我可以更深入地潜水时,还会有更多。
    猜你喜欢
    • 2018-11-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-23
    • 2019-11-07
    • 2019-02-25
    • 2017-10-21
    • 2020-04-09
    相关资源
    最近更新 更多