Python生成的zipfile已损坏

时间:2018-04-20 11:07:52

标签: python python-3.x flask

我有一个像下面这样的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)

对此的任何想法/帮助都非常感激。

1 个答案:

答案 0 :(得分:0)

问题不在于Python,而在于文件的下载方式。很明显,如果python测试通过,zip文件可能是合法的!如果您发现自己遇到同样的错误,请确保您的HTTP库期望得到正确的响应,对于axios,这意味着设置responseType to 'bytearray'