В v2 API вы можете использовать Object#copy_from()
или Object.copy_to()
с параметрами :metadata
и :metadata_directive => 'REPLACE'
для обновления метаданных объекта без его загрузки из S3.
Код в Суть Джуста выдает эту ошибку:
Aws :: S3 :: Errors :: InvalidRequest: этот запрос на копирование является недопустимым, поскольку
он пытается скопировать объект себе без изменения объекта
метаданные, класс хранения, местоположение перенаправления веб-сайта или шифрование
атрибутов.
Это связано с тем, что по умолчанию AWS игнорирует :metadata
, предоставленный с операцией копирования, поскольку копирует метаданные. Мы должны установить опцию :metadata_directive => 'REPLACE'
, если мы хотим обновить метаданные на месте.
См. http://docs.aws.amazon.com/sdkforruby/api/Aws/S3/Object.html#copy_from-instance_method
Вот полный рабочий фрагмент кода, который я недавно использовал для выполнения операций обновления метаданных:
require 'aws-sdk'
# S3 setup boilerplate
client = Aws::S3::Client.new(
:region => 'us-east-1',
:access_key_id => ENV['AWS_ACCESS_KEY'],
:secret_access_key => ENV['AWS_SECRET_KEY'],
)
s3 = Aws::S3::Resource.new(:client => client)
# Get an object reference
object = s3.bucket('my-bucket-name').object('my-object/key')
# Create our new metadata hash. This can be any hash; in this example we update
# existing metadata with a new key-value pair.
new_metadata = object.metadata.merge('MY_NEW_KEY' => 'MY_NEW_VALUE')
# Use the copy operation to replace our metadata
object.copy_to(object,
:metadata => new_metadata,
# IMPORTANT: normally S3 copies the metadata along with the object.
# we must supply this directive to replace the existing metadata with
# the values we supply
:metadata_directive => "REPLACE",
)
Для легкого повторного использования:
def update_metadata(s3_object, new_metadata = {})
s3_object.copy_to(s3_object,
:metadata => new_metadata
:metadata_directive => "REPLACE"
)
end