将 zip fileobj 上传到 S3 - KeyError:存档中没有名为 8388608 的项目

tur*_*nip 1 python amazon-s3 zipfile boto3

我正在尝试制作一个内存中的 zip 文件,其中包含一堆 JSON 文件。我正在努力将它作为文件对象上传到 S3,收到一个相当奇怪的错误。这是我的代码:

import boto3
import zipfile
import json
import os

session = boto3.session.Session(
        aws_access_key_id=os.environ.get('AWS_ACCESS_KEY_ID'),
        aws_secret_access_key=os.environ.get('AWS_SECRET_ACCESS_KEY'))
client = session.client('s3')

data = {'test1.json': {'a': 1, 'b': 2},
        'test2.json': {'x': 3, 'y': 4}}

zip_buffer = BytesIO()
zf = zipfile.ZipFile(zip_buffer, 'w')
for filename, d in data.iteritems():
    zf.writestr(filename, json.dumps(d, indent=4))

client.upload_fileobj(zf, os.environ.get('S3_BUCKET'), 'test_zip.zip')
Run Code Online (Sandbox Code Playgroud)

这给了我:

KeyError: 'There is no item named 8388608 in the archive'
Run Code Online (Sandbox Code Playgroud)

这是如何以及为什么发生的?当然8388608,档案中没有项目——我没有把它放在那里。


编辑

如果我将文件保存在本地而不是内存中,然后重新打开它,它工作正常。我应该使用tempfile吗?

tur*_*nip 5

这个问题是一个相当奇怪的问题。首先,zip_buffer需要通过的是 ,而不是zf但是,您需要确保先关闭 zipfile 对象,否则这将导致无法打开的损坏的 zip 文件。

import boto3
import zipfile
import json
import os

session = boto3.session.Session(
        aws_access_key_id=os.environ.get('AWS_ACCESS_KEY_ID'),
        aws_secret_access_key=os.environ.get('AWS_SECRET_ACCESS_KEY'))
client = session.client('s3')

data = {'test1.json': {'a': 1, 'b': 2},
        'test2.json': {'x': 3, 'y': 4}}

zip_buffer = BytesIO()
zf = zipfile.ZipFile(zip_buffer, 'w')
for filename, d in data.iteritems():
    zf.writestr(filename, json.dumps(d, indent=4))

zf.close()  # important!
zip_buffer.seek(0)

client.upload_fileobj(zip_buffer, os.environ.get('S3_BUCKET'), 'test_zip.zip')
Run Code Online (Sandbox Code Playgroud)