Boto3 S3 更新现有对象的元数据

Posted

技术标签:

【中文标题】Boto3 S3 更新现有对象的元数据【英文标题】:Boto3 S3 update metadata of existing object 【发布时间】:2017-07-16 06:09:42 【问题描述】:

这是一件奇怪的事情,我现在还无法理解。为什么当我使用 Boto3 将“过期”日期时间放在通过 put_object 放入 AWS S3 的对象上时,它会被存储并在 AWS cosnole 中显示为“元数据”。但是,当我检索对象时,我的“过期”日期时间显示为对象的日期时间元素,而不是元数据字典中的日期时间元素。

这个问题让我很困惑,但我在没有理解的情况下解决了这个问题。现在我想到了使用这种方法:How to update metadata of an existing object in AWS S3 using python boto3?,为了便于阅读,复制如下:

import boto3

s3 = boto3.resource('s3')
s3_object = s3.Object('bucket-name', 'key')
s3_object.metadata.update('id':'value')
s3_object.copy_from(
    CopySource='Bucket':'bucket-name', 'Key':'key', 
    Metadata=s3_object.metadata, MetadataDirective='REPLACE')

导致我的“过期”元数据被销毁。当然我试过这个:

metakeys.metadata.update('x-amz-meta-hell':'yes', 'expires': metakeys.expires)

但是会抛出:AttributeError: 'datetime.datetime' object has no attribute 'encode'

确实,您可以有效地更新元数据,而无需通过控制台破坏“过期”元素。所以在某种程度上我建议上面的方法要么是A:不可行或不正确,B:坏了,要么C:既坏又不正确

问题是 - 在不破坏 AWS S3 对象的这种或未来的奇怪行为的情况下更新对象元数据的正确方法是什么?

【问题讨论】:

【参考方案1】:

如果您使用“Expires”参数执行 put_object(),您应该会得到类似的结果。


    'Expiration': 'string',
    'ETag': 'string',
    ..........

但是,Expiration 是一个属性,它不是您的用户自定义元数据。所有用户自定义元数据只能是STRING,并且在您检查元数据时都将带有前缀x-amz-meta-

metakeys.metadata.update('x-amz-meta-hell':'yes', 'expires': metakeys.expires)

如果给定的metakeys.expires 不是字符串,上述更新将失败。它可以像使用 isoformat() 将其转换为字符串一样简单。

虽然 copy_object() 允许您指定明确的到期日期时间,但是 API 文档没有明确提到原始文件到期日期时间将被复制到目标对象。

【讨论】:

这与我使用此调用的经验一致。但是,更让我担心的是,我的“过期”标签被 CopySource='Bucket':'bucket-name', 'Key':'key', Metadata=s3_object.metadata, MetadataDirective='REPLACE') 覆盖而且我的“过期”标签也被 CopySource='Bucket':'bucket-name', 'Key':'key', Metadata=s3_object.metadata, MetadataDirective='COPY') 覆盖。因为我正在更新用户元数据,所以上述命令都不应该导致“过期”被覆盖,但它们确实会。 @Trip-G 我不确定您的“覆盖”的含义。 s3.copy_from() 不应更改您的 SOURCE 对象。它将对 TARGET 对象进行更改。

以上是关于Boto3 S3 更新现有对象的元数据的主要内容,如果未能解决你的问题,请参考以下文章

快速获取AWS S3对象元数据

使用 AWS Java 开发工具包为现有 S3 对象设置 Expires 标头

jclouds:如何更新现有 blob 的元数据?

如何使用 Amazon S3 SDK 更新元数据

如何使用 boto3 将文件或数据写入 S3 对象

boto3 S3 对象解析