Как изменить метаданные на объекте в Amazon S3 - PullRequest
35 голосов
/ 21 января 2011

Если вы уже загрузили объект в корзину Amazon S3, как вы можете изменить метаданные с помощью API? Это можно сделать в Консоли управления AWS, но неясно, как это можно сделать программно. В частности, я использую API-интерфейс boto в Python, и из чтения исходного кода ясно, что использование key.set_metadata работает только до , объект создается, поскольку он просто воздействует на локальный словарь.

Ответы [ 7 ]

36 голосов
/ 21 января 2011

Похоже, вам нужно перезаписать объект самим собой, используя «PUT Object (Copy)» с заголовком x-amz-metadata-directive: REPLACE в дополнение к метаданным. В boto это можно сделать так:

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

Обратите внимание, что любые метаданные, которые вы не включили в старый словарь, будут удалены. Таким образом, чтобы сохранить старые атрибуты, вам нужно сделать что-то вроде:

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;

Я почти пропустил это решение, на которое намекают во вступлении к некорректно озаглавленному вопросу, на самом деле о проблеме, отличной от этого вопроса: Изменить расположение содержимого существующего объекта S3

11 голосов
/ 14 мая 2013

Чтобы установить метаданные в файлах 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);`
7 голосов
/ 14 апреля 2015

Если вы хотите, чтобы ваши метаданные хранились удаленно, используйте set_remote_metadata

Пример: key.set_remote_metadata({'to_be': 'added'}, ['key', 'to', 'delete'], {True/False})

Реализация здесь: https://github.com/boto/boto/blob/66b360449812d857b4ec6a9834a752825e1e7603/boto/s3/key.py#L1875

5 голосов
/ 18 февраля 2012

Вы можете изменить метаданные без повторной загрузки объекта с помощью команды копирования. См. Этот вопрос: Можно ли изменить заголовки объекта S3 без загрузки всего объекта?

1 голос
/ 18 мая 2013

Для первого ответа рекомендуется включить в метаданные исходный тип контента, например:

key.set_metadata('Content-Type', key.content_type) 
0 голосов
/ 04 сентября 2015

вот код, который работал для меня. Я использую aws-java-sdk-s3 версия 1.10.15

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

s3Client.putObject(new PutObjectRequest(bucketName, keyName, tempFile)
                    .withMetadata(metadata));
0 голосов
/ 23 апреля 2015

В Java вы можете скопировать объект в то же место. Здесь метаданные не будут копироваться при копировании объекта. Вы должны получить метаданные оригинала и установить запрос на копирование. Этот метод более рекомендуется для вставки или обновления метаданных объекта 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);
...