python amazon-s3 boto

python - ¿Cómo puedo copiar archivos de más de 5 GB en Amazon S3?



amazon s3 python sdk (3)

Por lo que yo sé, no hay una operación de cambio de nombre o movimiento, por lo tanto, tengo que copiar el archivo a la nueva ubicación y eliminar el anterior.

Eso es correcto, es bastante fácil de hacer para objetos / archivos de menos de 5 GB mediante un objeto PUT - Copiar operación, seguido de una operación DELETE Object (ambos son compatibles con boto por supuesto, vea copy_key() y delete_key() )

Esta implementación de la operación PUT crea una copia de un objeto que ya está almacenado en Amazon S3. Una operación de copiado PUT es lo mismo que realizar un GET y luego un PUT. Al agregar el encabezado de solicitud, x-amz-copy-source, la operación PUT copia el objeto de origen en el depósito de destino.

Sin embargo, eso no es posible para objetos / archivos de más de 5 GB:

Nota
[...] Usted crea una copia de su objeto de hasta 5 GB de tamaño en una sola operación atómica usando esta API. Sin embargo, para copiar un objeto de más de 5 GB, debe usar la API de carga de varias partes . Para información conceptual [...], vaya a Cargar objetos usando Multipart Upload [...] [énfasis mío]

Mientras tanto, Boto también lo soporta mediante el método copy_part_from_key() ; desafortunadamente, el enfoque requerido no está documentado fuera de la solicitud de extracción respectiva # 425 (permitir comandos de copia de varias partes) (aunque aún no lo he probado):

import boto s3 = boto.connect_s3(''access'', ''secret'') b = s3.get_bucket(''destination_bucket'') mp = b.initiate_multipart_upload(''tmp/large-copy-test.mp4'') mp.copy_part_from_key(''source_bucket'', ''path/to/source/key'', 1, 0, 999999999) mp.copy_part_from_key(''source_bucket'', ''path/to/source/key'', 2, 1000000000, 1999999999) mp.copy_part_from_key(''source_bucket'', ''path/to/source/key'', 3, 2000000000, 2999999999) mp.copy_part_from_key(''source_bucket'', ''path/to/source/key'', 4, 3000000000, 3999999999) mp.copy_part_from_key(''source_bucket'', ''path/to/source/key'', 5, 4000000000, 4999999999) mp.copy_part_from_key(''source_bucket'', ''path/to/source/key'', 6, 5000000000, 5500345712) mp.complete_upload()

Es posible que desee estudiar las muestras respectivas sobre cómo lograr esto en Java o .NET eventualmente, lo que podría proporcionar más información sobre el enfoque general, consulte Copiar objetos utilizando la API de carga de varias partes .

¡Buena suerte!

Apéndice

Tenga en cuenta la siguiente peculiaridad con respecto a la copia en general, que se pasa por alto fácilmente:

Al copiar un objeto, puede conservar la mayoría de los metadatos (valor predeterminado) o especificar nuevos metadatos. Sin embargo, la ACL no se conserva y se establece en privado para el usuario que realiza la solicitud . Para anular la configuración de ACL predeterminada, use el encabezado x-amz-acl para especificar una nueva ACL al generar una solicitud de copia. Para obtener más información, consulte las LCA de Amazon S3. [énfasis mío]

La documentación de la API REST de Amazon S3 dice que hay un límite de tamaño de 5 gb para cargar en una operación PUT. Los archivos más grandes deben cargarse usando multiparte. Multa.

Sin embargo, lo que necesito en esencia es cambiar el nombre de los archivos que pueden ser más grandes que eso. Por lo que yo sé, no hay una operación de cambio de nombre o movimiento, por lo tanto, tengo que copiar el archivo a la nueva ubicación y eliminar el anterior. ¿Cómo exactamente eso se hace con archivos de más de 5 gb? Tengo que hacer una carga multiparte desde el cubo a sí mismo? En ese caso, ¿cómo funciona dividir el archivo en partes?

Al leer la fuente del boto, parece que no hace nada como esto automáticamente para archivos de más de 5 gb. ¿Hay algún soporte integrado que me perdí?


Encontré este método para cargar archivos de más de 5 gigs y modificarlo para que funcione con un procedimiento de copia de Boto. aquí está el original: http://boto.cloudhackers.com/en/latest/s3_tut.html

import math from boto.s3.connection import S3Connection from boto.exception import S3ResponseError conn = S3Connection(host=[your_host], aws_access_key_id=[your_access_key], aws_secret_access_key=[your_secret_access_key]) from_bucket = conn.get_bucket(''your_from_bucket_name'') key = from_bucket.lookup(''my_key_name'') dest_bucket = conn.get_bucket(''your_to_bucket_name'') total_bytes = key.size bytes_per_chunk = 500000000 chunks_count = int(math.ceil(total_bytes/float(bytes_per_chunk))) file_upload = dest_bucket.initiate_multipart_upload(key.name) for i in range(chunks_count): offset = i * bytes_per_chunk remaining_bytes = total_bytes - offset print(str(remaining_bytes)) next_byte_chunk = min([bytes_per_chunk, remaining_bytes]) part_number = i + 1 file_upload.copy_part_from_key(dest_bucket.name, key.name, part_number, offset, offset + next_byte_chunk - 1) file_upload.complete_upload()


Lo anterior estuvo muy cerca de funcionar, lamentablemente debería haber terminado con mp.complete_upload() lugar del error de tipo upload_complete() !

Agregué un script de copia multiparte de boto s3, aquí, basado en el ejemplo de AWS Java y probado con archivos de más de 5 GiB:

https://gist.github.com/joshuadfranklin/5130355