【发布时间】:2018-10-01 02:11:37
【问题描述】:
我有一个像下面这样的 Flask 视图,它生成几个 CSV 文件并将它们放在一个 zip 存档中以发送给用户。
@route('/download/<int:some_value>')
def download(self, some_value):
"""Return a ZIP archive with several CSVs in"""
# ensure the thing exists
at = (MyModel.SomeModel
.query
.filter((MyModel.SomeModel
.some_primary_key) == some_value)
.first_or_404())
# what queries do we need to run?
queries = cascade_export(at)
# prepare a zip
out = BytesIO()
with zipfile.ZipFile(out, 'w') as zf:
# run each query
for tn, q in queries.items():
# make the query
conn = db.engine.connect()
r = conn.execute(q.query, **q.params)
conn.close()
# map the col names
cols = [c.name for c in r.cursor.description]
col_map = {
c.name: c.key
for c in q.model.__table__.columns
}
col_order = [col_map[c] for c in cols]
# put it into a csv in memory
f = StringIO()
writer = csv.DictWriter(f, fieldnames=col_order)
for row in r:
writer.writerow({
k: v
for k, v in zip(col_order, row)
})
# write it into the zip
f.seek(0)
zf.writestr('{0}.csv'.format(q.model.__name__), f.read())
out.seek(0)
fn = 'export-{0}-{1}.zip'.format(
at.some_name,
datetime.datetime.now().strftime('%d-%m-%Y-%H-%M-%S')
)
return send_file(out,
attachment_filename=fn,
as_attachment=True,
cache_timeout=0)
在我的测试中,r 是一个响应对象,以下都通过:
assert r.status_code == 200
zf = zipfile.ZipFile(io.BytesIO(r.data))
assert zf.testzip() is None
但是,当我尝试在 ubuntu 中打开文件时,我得到以下信息:
Archive: ../downloads/export-Something-20-04-2018-11-59-04.zip
warning [../downloads/export-Something-20-04-2018-11-59-04.zip]: 300 extra bytes at beginning or within zipfile
(attempting to process anyway)
error [../downloads/export-Something-20-04-2018-11-59-04.zip]: start of central directory not found;
zipfile corrupt.
(please check that you have transferred or created the zipfile in the
appropriate BINARY mode and that you have compiled UnZip properly)
对此非常感谢的任何想法/帮助。
【问题讨论】:
-
尝试以二进制模式写入:
with zipfile.ZipFile(out, 'wb') as zf: -
这给了我
RuntimeError: ZipFile requires mode 'r', 'w', 'x', or 'a' -
你在客户端使用
requests吗? -
@jdehesa - 我正在使用烧瓶测试客户端 (
with app.test_client() as client:),python 似乎可以正常打开该文件,但是当我在浏览器中运行它并下载文件时,它已损坏。 -
如果我在浏览器中下载文件,然后尝试打开它,我会得到
zipfile.BadZipFile: Bad magic number for central directory
标签: python python-3.x flask