Flask模板流传输与Jinja

4
我有一个Flask应用程序。在特定的视图上,我展示了一张总共约有10万行的表格。可以理解地,页面加载需要很长时间,我正在寻找改进的方法。到目前为止,我已经确定了我查询数据库并相当快地获得结果。我认为问题在于渲染实际页面。我发现了this page on streaming,并尝试使用它,但一直遇到问题。我已经尝试了其中提供的stream_template解决方案,具体代码如下:
@app.route('/thing/matches', methods = ['GET', 'POST'])
@roles_accepted('admin', 'team')
def r_matches():
    matches = Match.query.filter(
            Match.name == g.name).order_by(Match.name).all()

    return Response(stream_template('/retailer/matches.html',
        dashboard_title = g.name,
        match_show_option = True,
        match_form = form,
        matches = matches))

def stream_template(template_name, **context):
    app.update_template_context(context)
    t = app.jinja_env.get_template(template_name)
    rv = t.stream(context)
    rv.enable_buffering(5)
    return rv

Match查询返回100k+项。但是,每当我运行它时,页面只会显示空白,什么也没有。我还尝试了通过流式传输数据到JSON并通过AJAX加载它的解决方案,但JSON文件中似乎也没有任何内容!以下是该解决方案的样子:

@app.route('/large.json')
def generate_large_json():
    def generate():
        app.logger.info("Generating JSON")
        matches = Product.query.join(Category).filter(
            Product.retailer == g.retailer,
            Product.match != None).order_by(Product.name)
        for match in matches:
            yield json.dumps(match)
    app.logger.info("Sending file response")
    return Response(stream_with_context(generate()))

另一个我正在考虑的解决方案是分页。这个解决方案很有效,但我需要能够通过标题对整个数据集进行排序,而且找不到不使用JQuery渲染整个数据集并用于排序/分页的方法。
通过访问/large.json获取的文件始终为空。请帮忙或推荐另一种显示如此大的数据集的方法!
编辑:我让generate()部分工作了,并更新了代码。
1个回答

2
在这两种情况下,问题几乎肯定是您正在构建10万个以上的Match项目并将它们存储在内存中。您还需要使用yield_per从数据库中流式传输结果。但是,只有PostGres+psycopg2支持必要的stream_result参数(这里有一种使用MySQL的方法):
matches = Match.query.filter(
        Match.name == g.name).order_by(Match.name).yield_per(10)
        # Stream ten results at a time

另一种选择

如果您正在使用Flask-SQLAlchemy,您可以利用其Pagination对查询进行分页处理,从而在服务器端分页处理,而不是将所有10万多个条目加载到浏览器中。这样做的额外好处是不需要浏览器管理所有DOM条目(假设您正在使用HTML流选项)。

另请参阅


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接