web-dev-qa-db-fra.com

Comment changer des métadonnées sur un objet dans Amazon S3

Si vous avez déjà téléchargé un objet dans un compartiment Amazon S3, comment modifiez-vous les métadonnées à l'aide de l'API? Il est possible de le faire dans la AWS Management Console, mais il n'est pas clair comment cela pourrait être fait par programme. Plus précisément, j'utilise l'API boto dans Python et à la lecture de la source, il est clair que l'utilisation de key.set_metadata ne fonctionne que avant l'objet est créé tel qu'il vient effectue un dictionnaire local.

35
natevw

Il semble que vous devez écraser l'objet avec lui-même, en utilisant un "PUT Object (Copy)" avec un x-amz-metadata-directive: REPLACE en-tête en plus des métadonnées. En boto, cela peut se faire comme ceci:

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

Notez que toutes les métadonnées que vous n'incluez pas dans l'ancien dictionnaire seront supprimées. Donc, pour conserver les anciens attributs, vous devrez faire quelque chose comme:

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;

J'ai failli manquer cette solution, qui est suggérée dans l'intro à une question incorrectement intitulée qui concerne en fait un problème différent de cette question: Changer le contenu-Disposition de l'objet S3 existant

36
natevw

Afin de définir des métadonnées sur des fichiers S3, ne fournissez tout simplement pas l'emplacement cible car seules les informations source sont suffisantes pour définir des métadonnées.

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);`
11
kartik

Si vous souhaitez que vos métadonnées soient stockées à distance, utilisez set_remote_metadata

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

L'implémentation est ici: https://github.com/boto/boto/blob/66b360449812d857b4ec6a9834a752825e1e7603/boto/s3/key.py#L1875

8
eddd

Vous pouvez modifier les métadonnées sans recharger l'objet à l'aide de la commande de copie. Voir cette question: Est-il possible de changer les en-têtes d'un objet S3 sans télécharger l'intégralité de l'objet?

5
John Bachir

Pour la première réponse, c'est une bonne idée d'inclure le type de contenu d'origine dans les métadonnées, par exemple:

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