Necesito cambiar algunos metadatos (Content-Type) en cientos o miles de objetos en S3. ¿Cuál es una buena forma de hacer esto con ruby? Por lo que puedo decir, no hay forma de guardar solo metadatos con fog.io, se debe volver a guardar todo el objeto. Parece que usar the official sdk library requeriría que rodara un entorno de envoltura solo para esta tarea.¿Cómo actualizo un lote de metadatos de objetos S3 usando ruby?
Respuesta
Tiene razón, el SDK oficial le permite modificar los metadatos del objeto sin cargarlo nuevamente. Lo que hace es copy the object, pero está en el servidor, por lo que no necesita descargar el archivo y volver a subirlo.
Una envoltura sería fácil de implementar, algo así como
bucket.objects.each do |object|
object.metadata['content-type'] = 'application/json'
end
Para los futuros lectores, he aquí una muestra completa de cambiar las cosas mediante el rubí v1 AWS-SDK (ver también este Gist para un v2 AWS-SDK de la muestra):
# Using v1 of Ruby aws-sdk as currently v2 seems not able to do this (broken?).
require 'aws-sdk-v1'
key = YOUR_AWS_KEY
secret = YOUR_AWS_SECRET
region = YOUR_AWS_REGION
AWS.config(access_key_id: key, secret_access_key: secret, region: region)
s3 = AWS::S3.new
bucket = s3.buckets[bucket_name]
bucket.objects.with_prefix('images/').each do |obj|
puts obj.key
# Add metadata: {} to next line for more metadata.
obj.copy_from(obj.key, content_type: obj.content_type, cache_control: 'max-age=1576800000', acl: :public_read)
end
Su Gist dice que la muestra v2 no parece funcionar, y sugiere que podría ser un error en el SDK ... ¿Supongo que aún no lo ha resuelto? – scottb
No. Simplemente pruebe la esencia con la última versión de v2 :) – joost
versión v2 no funciona para mí tampoco. He comentado la esencia de mi solución (volver a cargar cada archivo). –
En la versión 2 del API, puede utilizar Object#copy_from()
o Object.copy_to()
con los :metadata
y :metadata_directive => 'REPLACE'
opciones para actualizar los metadatos de un objeto sin necesidad de descargarlo desde S3.
El código en Joost's gist tiros este error:
Aws::S3::Errors::InvalidRequest: This copy request is illegal because it is trying to copy an object to itself without changing the object's metadata, storage class, website redirect location or encryption attributes.
Esto es porque por defecto AWS ignora el :metadata
suministrado con una operación de copia ya que copia los metadatos. Debemos establecer la opción :metadata_directive => 'REPLACE'
si queremos actualizar los metadatos en contexto.
Ver http://docs.aws.amazon.com/sdkforruby/api/Aws/S3/Object.html#copy_from-instance_method
Aquí hay una, fragmento completo trabajando código que recientemente he utilizado para llevar a cabo las operaciones de actualización de metadatos:
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",
)
Para una fácil reutilización:
def update_metadata(s3_object, new_metadata = {})
s3_object.copy_to(s3_object,
:metadata => new_metadata
:metadata_directive => "REPLACE"
)
end
Para agregar control de caché use: object.copy_to (object, cache_control: 'public, max-age = 333333', metadata_directive: 'REPLACE') –
buscándole esto parece funcionar para mí
obj.copy_to(obj, :metadata_directive=>"REPLACE", :acl=>"public-read",:content_type=>"text/plain")
- 1. Cómo cambiar los metadatos en un objeto en Amazon S3
- 2. Cómo actualizo Ruby Gems detrás de un Proxy (ISA-NTLM)
- 3. ¿Cómo actualizo los miembros de un objeto usando un dict?
- 4. ¿Manera eficiente de extraer archivos y metadatos de Amazon S3?
- 5. Notificación de nuevos objetos S3
- 6. ¿Cómo actualizo los intérpretes de Ruby con RVM?
- 7. Límite S3 para objetos en un cubo
- 8. ¿Cómo actualizo mi ruby 1.9.2-p0 al último nivel de parche usando rvm?
- 9. Intentando establecer metadatos en el archivo de Amazon S3 usando s3cmd
- 10. ¿Cómo elimino/cuento objetos en un cubo s3?
- 11. ¿Insertar/actualizar lote usando Mongoid?
- 12. Configurando el propietario de los objetos en un cubo S3
- 13. Usando SQL, ¿cómo actualizo las filas, usando sus propios valores?
- 14. ¿Cómo actualizo un paquete de Python?
- 15. ¿Cómo actualizo un atributo XML de un script de MSBuild?
- 16. Cómo enumerar _todos_ objetos en el cubo de Amazon S3?
- 17. ¿Cómo recorre cada línea en un archivo de texto usando un archivo de lote de Windows?
- 18. ¿Cómo obtener metadatos de películas de IMDB usando Java?
- 19. Python: Usando Hachoir, ¿cómo se extraen metadatos para objetos similares a archivos?
- 20. ¿Cómo borro/actualizo un documento con lucene?
- 21. Envío de estilo S3 para objetos S3 utilizando las definiciones de métodos formales
- 22. Obtener metadatos de SHOUTcast usando IcyStreamMeta
- 23. ¿Cómo actualizo Homebrew?
- 24. ¿Cómo actualizo la versión de un plugin maven?
- 25. ¿Cómo actualizo una entidad usando spring-data-jpa?
- 26. ¿Cómo actualizo a addEventListener?
- 27. ¿Cómo actualizo todos los paquetes actualizables usando ppm?
- 28. ¿Puede etiquetar objetos individuales S3 en AWS?
- 29. ¿Cómo actualizo el boto lib de python?
- 30. OpenGL: ¿forma eficiente de renderizar un lote de geometría?
Más discusión sobre esto aquí: http://groups.google.com/group/ruby-fog/browse_thread/thread/e632fc61405bf04c –
esto agrega solo metadatos con x-amz-meta- prefix. ¿Hay alguna forma de agregar solo un metadato normal de tipo de contenido? – serengeti12