我正在尝试制作一个内存中的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')
这给了我:
KeyError: 'There is no item named 8388608 in the archive'
这是怎么发生的?当然档案中没有项目8388608
- 我没有把它放在那里。
修改
如果我在本地而不是在内存中保存文件然后重新打开它,它可以正常工作。我应该使用tempfile
吗?
答案 0 :(得分:0)
这个问题很奇怪。首先,需要传递的是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')