我正在尝试将文件从s3移动到Glacier。这是我的代码
s3 = boto3.resource('s3')
S3_BUCKET = 'bucket_name'
client = boto3.client('glacier')
bucket = s3.Bucket(S3_BUCKET)
def glacier():
response = client.create_vault(
vaultName='sample_vault')
for obj in bucket.objects.all():
#downloading files from s3
key = str(obj.key)
print("key is ", key)
data_stream = io.BytesIO()
s3.meta.client.download_fileobj(S3_BUCKET, key,data_stream)
print("downloaded file", data_stream)
upload = client.upload_archive(
vaultName='sample_vault',
archiveDescription='string',
body=data_stream
)
print("uploaded", key)
但是我得到了InvalidParameterValueException错误。
[ERROR] InvalidParameterValueException: An error occurred (InvalidParameterValueException) when calling the UploadArchive operation: Invalid Content-Length: 0 Traceback (most recent call last):
File "/var/task/lambda_function.py", line 34, in lambda_handler
upload = client.upload_archive(
File "/var/runtime/botocore/client.py", line 386, in _api_call
return self._make_api_call(operation_name, kwargs)
File "/var/runtime/botocore/client.py", line 705, in _make_api_call
raise error_class(parsed_response, operation_name)
这是使用io.BytesIO((方法的正确方法吗?。我也尝试过bucket.download_file(S3_BUCKET,obj,'/tmp/'+key)
,但得到了ValueError。我在这里做错了什么?
有两个AWS服务使用"Glacier"一词。
-
有一个"真正的">亚马逊冰川服务,它使用金库和档案。它速度慢,几乎不可能使用,几乎没有管理控制台,而且比S3选项(如下(更贵。
-
亚马逊S3中也提供了冰川存储类。可以使用标准S3 API调用(如AWS CLI(和管理控制台将对象上载到Amazon S3。这些存储类别比亚马逊冰川便宜。
简而言之,再也没有合理的理由使用"旧"亚马逊冰川了。我建议您改用S3存储类。
关于您的特定错误:Invalid Content-Length: 0
看起来你正试图将一个档案上传到Glacier,那里的档案长度为零。这可能是因为代码试图上载一个零长度的对象,该对象用于标识目录。
解释:当在Amazon S3管理控制台中使用创建文件夹按钮时,会创建一个与目录同名的零长度对象(例如invoices/
(。这个零长度的对象"强制"显示目录,即使该路径中没有对象。
很可能您的代码正试图将这些零长度对象之一上传到Glacier。为了避免这种情况发生,您的代码可以跳过任何路径以斜杠(/
(结尾的对象。
我也遇到了同样的错误,这是因为您正在从文件的末尾读取文件。
s3 = boto3.resource('s3')
S3_BUCKET = 'bucket_name'
client = boto3.client('glacier')
bucket = s3.Bucket(S3_BUCKET)
def glacier():
response = client.create_vault(
vaultName='sample_vault')
for obj in bucket.objects.all():
#downloading files from s3
key = str(obj.key)
print("key is ", key)
data_stream = io.BytesIO()
s3.meta.client.download_fileobj(S3_BUCKET, key,data_stream)
print("downloaded file", data_stream)
data_stream.seek(0) #take pointer back to zero before uploading
upload = client.upload_archive(
vaultName='sample_vault',
archiveDescription='string',
body=data_stream
)
print("uploaded", key)
`