Flask:使用 stream_with_context 流式传输文件非常慢

Max*_* L. 3 flask flask-sqlalchemy

以下代码将 postgres BYTEA 列流式传输到浏览器

from flask import Response, stream_with_context

@app.route('/api/1/zfile/<file_id>', methods=['GET'])
def download_file(file_id):

    file = ZFile.query.filter_by(id=file_id).first()
    return Response(stream_with_context(file.data), mimetype=file.mime_type)
Run Code Online (Sandbox Code Playgroud)

它非常慢(5 mb 大约需要 6 分钟)。

我正在从同一台主机上使用 curl 下载,所以网络不是问题,而且我可以在不到一秒钟的时间内从 psql 控制台提取文件,所以似乎数据库端也不应该受到指责:

COPY (select f.data from z_file f where f.id = '4ec3rf') TO 'zazX.pdf' (FORMAT binary)
Run Code Online (Sandbox Code Playgroud)

更新:

我有进一步的证据表明“从数据库中获取”步骤并不慢,如果我使用 file.data 将 file.data 写入文件

with open("/vagrant/zoz.pdf", 'wb') as output:
    output.write(file.data)
Run Code Online (Sandbox Code Playgroud)

它也需要几分之一秒。所以缓慢是由 Flask 进行流式传输的方式引起的。

Dav*_*mic 5

我在使用 Flask 使用 python-requests 从另一个 url 代理流时遇到了这个问题。

在这个用例中,技巧是在 iter_content 中设置 chunk_size 参数:

def flask_view():
    ...
    req = requests.get(url, stream=True, params=args)
    return Response(
        stream_with_context(req.iter_content(chunk_size=1024)),
        content_type=req.headers['content-type']
Run Code Online (Sandbox Code Playgroud)

否则它会使用 chunk_size=1,这会大大减慢速度。在我的情况下,在增加 chunk_size 后,流从几 kb/s 变为几 mb/s。