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

Posted

技术标签:

【中文标题】将 zip 文件 obj 上传到 S3 - KeyError:存档中没有名为 8388608 的项目【英文标题】:Uploading a zip fileobj to S3 - KeyError: There is no item named 8388608 in the archive 【发布时间】:2018-03-23 14:31:25 【问题描述】:

我正在尝试制作一个内存中的 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 吗?

【问题讨论】:

内存中的处理总是令人困惑。看一下这个。 ***.com/questions/3610221/… @mootmoot 我已经在创建内存压缩包了,我认为这可能更像是一个boto3 问题。 这不是boto3的问题,你需要传递正确的文件对象,肯定不是zf,而是缓冲区对象。这就是我说内存处理令人困惑的原因。 我发现了怎么回事。我已经尝试过传递zip_buffer,它可以工作,但它导致了无效的 zip 文件(Windows / 3rd 方工具无法打开它们)。问题是我在上传之前没有关闭zf。有趣的神器... 好吧,你可以发布你的解决方案,其实解决方案就在那里。 【参考方案1】:

这个问题相当奇怪。首先,需要传递的是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')

【讨论】:

以上是关于将 zip 文件 obj 上传到 S3 - KeyError:存档中没有名为 8388608 的项目的主要内容,如果未能解决你的问题,请参考以下文章

Boto3没有将zip文件上传到S3 python

上传 ZIP 文件到 S3,使用 EC2 解压

内存中的 zip 文件上传一个 0 B 对象

使用 Java 在 S3 中更新 zip 文件

从 s3 存储桶获取 2 个文件,并在使用 lambda 节点 js 将其上传到 s3 存储桶后制作 1 个 zip 文件

使用带有 Node.js 的 AWS Lambda 函数从 S3 存储桶中提取 zip 文件并上传到另一个存储桶