suraj tikoo
suraj tikoo

Reputation: 61

Updating existing metadata of my S3 object

I am trying to update the existing metadata of my S3 object but in spite of updating it is creating the new one. As per the documentation, it is showing the same way but don't know why it is not able to update it.

 k = s3.head_object(Bucket='test-bucket', Key='test.json')
            s3.copy_object(Bucket='test-bucket', Key='test.json', CopySource='test-bucket' + '/' + 'test.json', Metadata={'Content-Type': 'text/plain'}, MetadataDirective='REPLACE')

Upvotes: 1

Views: 2516

Answers (3)

javafueled
javafueled

Reputation: 524

I came here looking clues on how to do the same. The same can be done with the Java SDK:

...
    try {
      HeadObjectResponse response =
          s3Client.headObject(HeadObjectRequest.builder().bucket(sourceBucket).key(uuid).build());
      // ...
      // update the metadata Map from the request
      // you MUST use a copy of the data, i.e.,
      // Map<String, String> patchMap = new HashMap<>(response.metadata());
      // HeadObjectResponse#metadata() returns a Map keys WITHOUT the 'x-amz-meta-' prefix. Patch values in the patchMap using the "short key," 
      // i.e., patchMap.replace("key", "value"), not patchMap.replace("x-amz-meta-key", "value").
      // ...
      s3Client.copyObject(CopyObjectRequest
          .builder()
          .metadataDirective("REPLACE")
          .sourceBucket(sourceBucket)
          .sourceKey(uuid)
          .destinationBucket(sourceBucket)
          .destinationKey(uuid)
          .metadata(map)
          .build());
      HeadObjectResponse updated =
          s3Client.headObject(HeadObjectRequest.builder().bucket(sourceBucket).key(uuid).build());
      return ResponseEntity.ok(
          new SuccessDocument().data(new Resource().type("document").id(uuid).attributes(updated.metadata())));
    } catch (NoSuchKeyException nske) {
      throw new ResponseStatusException(HttpStatus.NOT_FOUND);
    }

HashMap(Map<? extends K,? extends V> m)

The metadata is retrieved in the HeadObjectResponse. Modified in the map and the ResponseEntity is returned in the SuccessDocument. This example is modeled on the json:api, a HAL/HATEOAS specification.

Upvotes: 0

suraj tikoo
suraj tikoo

Reputation: 61

I was able to update using the copy_from method

s3 = boto3.resource('s3')
object = s3.Object(bucketName, uploadedKey)
object.copy_from(
    CopySource={'Bucket': bucketName,'Key': uploadedKey},
    MetadataDirective="REPLACE",
    ContentType=value
) 

Upvotes: 2

Exelian
Exelian

Reputation: 5888

S3 metadata is read-only, so updating only metadata of an S3 object is not possible. The only way to update the metadata is to recreate/copy the object. Check the 1st paragraph of the official docs

You can set object metadata at the time you upload it. After you upload the object, you cannot modify object metadata. The only way to modify object metadata is to make a copy of the object and set the metadata.

Upvotes: 1

Related Questions