以下代码将 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)
速度极慢(5 mb 大约需要 6 分钟)。
我使用 curl 从同一主机下载,所以网络不是问题, 我也可以在不到一秒的时间内从 psql 控制台中提取文件, 所以看来数据库方面也不是罪魁祸首:
COPY (select f.data from z_file f where f.id = '4ec3rf') TO 'zazX.pdf' (FORMAT binary)
更新:
我有进一步的证据表明“从数据库中获取”步骤并不慢,如果我使用
将 file.data 写入文件with open("/vagrant/zoz.pdf", 'wb') as output:
output.write(file.data)
它也只需要几分之一秒。所以缓慢是由 Flask 进行流式传输的方式引起的。
最佳答案
我在使用 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']
否则它将使用 chunk_size=1,这会减慢速度。在我的情况下,在 chunk_size 增加后,流从几 kb/s 变为几 mb/s。
关于Flask:带有stream_with_context的流文件非常慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34229349/