Usando el módulo boto3 de python, permítanme decirlo nuevamente, usando boto3 , no boto . ¿Cómo puedo descargar un archivo de S3, gzip y volver a cargarlo en S3 sin que el archivo se escriba en el disco?
Estoy tratando de escribir una función AWS lambda que Gzips todo el contenido cargado en S3. El problema es que una función lambda está limitada a 512 MB de espacio en disco y mis cargas podrían superar con creces esto.
Mi suposición es que puede ser posible hacer esto usando transmisiones, ¡cualquier ayuda sería muy apreciada! Gracias.
[ACTUALIZAR]
El siguiente código funciona, más o menos. Cargará los fragmentos en S3 y puedo ver el archivo *.gz resultante. Sin embargo, los encabezados gzip no se agregan correctamente. Abrir el archivo da como resultado en mac Error 32 - Broken Pipe .
Dato interesante, si el tamaño del archivo es menor que CHUNK_SIZE , es decir, solo una iteración, el archivo se carga y no está dañado.
Cualquiera ve algo que estoy haciendo mal?
CHUNK_SIZE = 10000000 gz_buffer = io.BytesIO() gz_stream = gzip.GzipFile(fileobj=gz_buffer, mode='wb', compresslevel=9) obj = resource.Object(bucket, key) body = obj.get()['Body'] try: while True: data = body.read(CHUNK_SIZE) if data: compressed_bytes = gz_stream.write(data) if compressed_bytes < CHUNK_SIZE: gz_stream.close() cdata = gz_buffer.getvalue()[0:compressed_bytes] # Upload cdata as multipart upload # This is a little helper function that # uses boto3 create_multipart_upload multipart.upload(cdata) else: # Signal to S3 complete multipart upload multipart.complete() break except Exception as e: passYo haría esto:
import gzip,io out_buffer = io.BytesIO() f = gzip.open(out_buffer,"wb") obj = resource.Object(bucket, key) body = obj.get()['Body'] while True: read = body.read(500000) print('reading...') if read: # 1.) Stream chunks to gzip f.seek(0) nb_bytes = f.write(read) # 2.) Stream compressed chunks back to S3 cdata = out_buffer.getvalue()[0:nb_bytes] # cdata now holds the compressed chunk of data else: breakio.BytesIO para crear un archivo "falso" en la memoriaout_buffer no se reduce, por lo que debemos saber la longitud tenga en cuenta que en python 2.x, no puede pasar un objeto de archivo a gzip.open , debe crear un objeto Gzip en su lugar, como este:
f = gzip.GzipFile("foo.gz","wb",fileobj=out_buffer)