简体   繁体   English

如何在Amazon S3中更改对象上的元数据

[英]How to change metadata on an object in Amazon S3

If you have already uploaded an object to an Amazon S3 bucket, how do you change the metadata using the API? 如果您已经将对象上传到Amazon S3存储桶,那么如何使用API​​更改元数据? It is possible to do this in the AWS Management Console, but it is not clear how it could be done programmatically. 可以在AWS管理控制台中执行此操作,但尚不清楚如何以编程方式完成此操作。 Specifically, I'm using the boto API in Python and from reading the source it is clear that using key.set_metadata only works before the object is created as it just effects a local dictionary. 具体来说,我在Python中使用boto API,从阅读源代码中可以明显看出,使用key.set_metadata仅创建对象之前有效 ,因为它只会影响本地字典。

It appears you need to overwrite the object with itself, using a "PUT Object (Copy)" with an x-amz-metadata-directive: REPLACE header in addition to the metadata. 看来您需要使用带有x-amz-metadata-directive: REPLACE标头的“ PUT对象(复制)”以及x-amz-metadata-directive: REPLACE来覆盖对象本身。 In boto, this can be done like this: 在boto中,可以这样进行:

k = k.copy(k.bucket.name, k.name, {'myKey':'myValue'}, preserve_acl=True)

Note that any metadata you do not include in the old dictionary will be dropped. 请注意,您未包含在旧词典中的任何元数据都将被删除。 So to preserve old attributes you'll need to do something like: 因此,要保留旧属性,您需要执行以下操作:

k.metadata.update({'myKey':'myValue'})
k2 = k.copy(k.bucket.name, k.name, k.metadata, preserve_acl=True)
k2.metadata = k.metadata    # boto gives back an object without *any* metadata
k = k2;

I almost missed this solution, which is hinted at in the intro to an incorrectly-titled question that's actually about a different problem than this question: Change Content-Disposition of existing S3 object 我差点错过了此解决方案,在介绍不正确标题的问题中暗示了这一问题,该问题实际上是与该问题不同的问题: 更改现有S3对象的Content-Disposition

In order to set metadata on S3 files,just don't provide target location as only source information is enough to set metadata. 为了在S3文件上设置元数据,请不要提供目标位置,因为仅源信息就足以设置元数据。

final ObjectMetadata metadata = new ObjectMetadata();
metadata.addUserMetadata(metadataKey, value);
final CopyObjectRequest request = new CopyObjectRequest(bucketName, keyName, bucketName, keyName)
  .withSourceBucketName(bucketName)
  .withSourceKey(keyName)
  .withNewObjectMetadata(metadata);

s3.copyObject(request);`

If you want your metadata stored remotely use set_remote_metadata 如果要元数据远程存储,请使用set_remote_metadata

Example: key.set_remote_metadata({'to_be': 'added'}, ['key', 'to', 'delete'], {True/False}) 示例: key.set_remote_metadata({'to_be': 'added'}, ['key', 'to', 'delete'], {True/False})

Implementation is here: https://github.com/boto/boto/blob/66b360449812d857b4ec6a9834a752825e1e7603/boto/s3/key.py#L1875 实现在这里: https : //github.com/boto/boto/blob/66b360449812d857b4ec6a9834a752825e1e7603/boto/s3/key.py#L1875

You can change the metadata without re-uloading the object by using the copy command. 您可以使用copy命令更改元数据而无需重新加载对象。 See this question: Is it possible to change headers on an S3 object without downloading the entire object? 看到这个问题: 是否可以在不下载整个对象的情况下更改S3对象上的标头?

对于第一个答案,最好在元数据中包含原始内容类型,例如:

key.set_metadata('Content-Type', key.content_type) 

In Java, You can copy object to the same location. 在Java中,您可以将对象复制到同一位置。 Here metadata will not copy while copying an Object. 在此,复制对象时不会复制元数据。 You have to get metadata of original and set to copy request. 您必须获取原始元数据并设置为复制请求。 This method is more recommended to insert or update metadata of an Amazon S3 object 推荐使用此方法来插入或更新Amazon S3对象的元数据

ObjectMetadata metadata = amazonS3Client.getObjectMetadata(bucketName, fileKey);
ObjectMetadata metadataCopy = new ObjectMetadata();
metadataCopy.addUserMetadata("yourKey", "updateValue");
metadataCopy.addUserMetadata("otherKey", "newValue");
metadataCopy.addUserMetadata("existingKey", metadata.getUserMetaDataOf("existingValue"));

CopyObjectRequest request = new CopyObjectRequest(bucketName, fileKey, bucketName, fileKey)
      .withSourceBucketName(bucketName)
      .withSourceKey(fileKey)
      .withNewObjectMetadata(metadataCopy);

amazonS3Client.copyObject(request);

here is the code that worked for me. 这是对我有用的代码。 I'm using aws-java-sdk-s3 version 1.10.15 我正在使用aws-java-sdk-s3版本1.10.15

ObjectMetadata metadata = new ObjectMetadata();
metadata.setContentType(fileExtension.getMediaType());

s3Client.putObject(new PutObjectRequest(bucketName, keyName, tempFile)
                    .withMetadata(metadata));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM