Cómo cambiar metadatos en un objeto en Amazon S3

Si ya ha cargado un objeto en un depósito de Amazon S3, ¿cómo cambia los metadatos utilizando la API? Es posible hacer esto en la Consola de administración de AWS, pero no está claro cómo podría hacerse mediante progtwigción. Específicamente, estoy usando la API de boto en Python y, al leer la fuente, está claro que usar key.set_metadata solo funciona antes de que se cree el objeto, ya que solo afecta a un diccionario local.

Parece que necesita sobrescribir el objeto con él mismo, utilizando un “Objeto PUT (Copiar)” con una x-amz-metadata-directive: REPLACE además de los metadatos. En boto, esto se puede hacer así:

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

Tenga en cuenta que todos los metadatos que no incluya en el diccionario anterior se eliminarán. Entonces, para preservar los atributos antiguos, necesitarás hacer algo como:

 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; 

Casi me perdí esta solución, que se insinúa en la introducción de una pregunta con un título incorrecto que en realidad trata sobre un problema diferente al de esta pregunta: Cambiar contenido-Disposición del objeto S3 existente

Para establecer los metadatos en los archivos S3, simplemente no proporcione la ubicación de destino, ya que solo la información de origen es suficiente para configurar los metadatos.

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

Si desea que sus metadatos se almacenen de forma remota, use set_remote_metadata

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

La implementación está aquí: https://github.com/boto/boto/blob/66b360449812d857b4ec6a9834a752825e1e7603/boto/s3/key.py#L1875

Puede cambiar los metadatos sin volver a cargar el objeto mediante el comando de copia. Vea esta pregunta: ¿Es posible cambiar los encabezados en un objeto S3 sin descargar todo el objeto?

Para la primera respuesta, es una buena idea incluir el tipo de contenido original en los metadatos, por ejemplo:

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

En Java, puede copiar el objeto a la misma ubicación. Aquí los metadatos no se copiarán mientras se copia un objeto. Tienes que obtener los metadatos del original y configurar para copiar la solicitud. Este método es más recomendado para insertar o actualizar metadatos de un objeto de 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); 

Aquí está el código que me funcionó. Estoy usando aws-java-sdk-s3 versión 1.10.15

 ObjectMetadata metadata = new ObjectMetadata(); metadata.setContentType(fileExtension.getMediaType()); s3Client.putObject(new PutObjectRequest(bucketName, keyName, tempFile) .withMetadata(metadata));