以下代码将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分钟大约6分钟)。
我正在使用curl从同一主机下载,因此网络不是问题, 我也可以在不到一秒的时间内从psql控制台中提取文件, 所以看来数据库方面也不应该受到责备:
COPY (select f.data from z_file f where f.id = '4ec3rf') TO 'zazX.pdf' (FORMAT binary)
我还有进一步的证据表明&#34;从数据库中获取&#34;步骤不慢,如果我使用
将file.data写入文件with open("/vagrant/zoz.pdf", 'wb') as output:
output.write(file.data)
它也需要几分之一秒。因此,缓慢是由Flask进行流式传输的方式引起的。
答案 0 :(得分:2)
我在使用Flask使用python-requests代理来自其他网址的流媒体时遇到了这个问题。
在这个用例中,诀窍是在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。
答案 1 :(得分:0)
Flask可以被赋予一个生成器,它以单个yield返回整个数组,并且“知道”如何处理它,这将以毫秒为单位返回:
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()
def single_chunk_generator():
yield file.data
return Response(stream_with_context(single_chunk_generator()), mimetype=file.mime_type)
stream_with_context ,当给定数组时,将创建一个生成器,迭代它并对每个元素进行各种检查,这会导致巨大的性能损失。