Saltar al contenido

¿Cómo extraer archivos en S3 sobre la marcha con boto3?

Este escrito fue analizado por nuestros expertos para que tengas la garantía de la exactitud de nuestro post.

Solución:

Puede usar BytesIO para transmitir el archivo desde S3, ejecutarlo a través de gzip y luego canalizarlo nuevamente a S3 usando upload_fileobj para escribir el BytesIO.

# python imports
import boto3
from io import BytesIO
import gzip

# setup constants
bucket = ''
gzipped_key = ''
uncompressed_key = ''

# initialize s3 client, this is dependent upon your aws config being done 
s3 = boto3.client('s3', use_ssl=False)  # optional
s3.upload_fileobj(                      # upload a new obj to s3
    Fileobj=gzip.GzipFile(              # read in the output of gzip -d
        None,                           # just return output as BytesIO
        'rb',                           # read binary
        fileobj=BytesIO(s3.get_object(Bucket=bucket, Key=gzipped_key)['Body'].read())),
    Bucket=bucket,                      # target bucket, writing to
    Key=uncompressed_key)               # target key, writing to

Asegúrese de que su key está leyendo correctamente:

# read the body of the s3 key object into a string to ensure download
s = s3.get_object(Bucket=bucket, Key=gzip_key)['Body'].read()
print(len(s))  # check to ensure some data was returned

Amazon S3 es un servicio de almacenamiento. No hay una capacidad incorporada para manipular el contenido de los archivos.

Sin embargo, podría usar una función de AWS Lambda para recuperar un objeto de S3, descomprimirlo y luego volver a cargar el contenido. Sin embargo, tenga en cuenta que existe un límite de 500 MB de espacio temporal en disco para Lambda, así que evite descomprimir demasiados datos.

Puede configurar el depósito S3 para activar la función Lambda cuando se crea un nuevo archivo en el depósito. La función Lambda entonces:

  • Use boto3 (suponiendo que le guste Python) para descargar el nuevo archivo
  • Utilizar el zipfile Biblioteca de Python para extraer archivos
  • Use boto3 para cargar los archivos resultantes

Código de muestra

import boto3

s3 = boto3.client('s3', use_ssl=False)
s3.upload_fileobj(
    Fileobj=gzip.GzipFile(
        None,
        'rb',
        fileobj=BytesIO(
            s3.get_object(Bucket=bucket, Key=gzip_key)['Body'].read())),
    Bucket=bucket,
    Key=uncompressed_key)

Las respuestas anteriores son para gzip archivos, para zip archivos, puede intentar

import boto3
import zipfile
from io import BytesIO
bucket = 'bucket1'

s3 = boto3.client('s3', use_ssl=False)
Key_unzip = 'result_files/'

prefix      = "folder_name/"
zipped_keys =  s3.list_objects_v2(Bucket=bucket, Prefix=prefix, Delimiter = "/")
file_list = []
for key in zipped_keys['Contents']:
    file_list.append(key['Key'])
#This will give you list of files in the folder you mentioned as prefix
s3_resource = boto3.resource('s3')
#Now create zip object one by one, this below is for 1st file in file_list
zip_obj = s3_resource.Object(bucket_name=bucket, key=file_list[0])
print (zip_obj)
buffer = BytesIO(zip_obj.get()["Body"].read())

z = zipfile.ZipFile(buffer)
for filename in z.namelist():
    file_info = z.getinfo(filename)
    s3_resource.meta.client.upload_fileobj(
        z.open(filename),
        Bucket=bucket,
        Key='result_files/' + f'filename')

Esto funcionará para su zip archivo y su resultado datos descomprimidos estarán en result_files carpeta. Asegúrese de aumentar la memoria y el tiempo en AWS Lambda al máximo ya que algunos archivos son bastante grandes y necesitan tiempo para escribirse.

Más adelante puedes encontrar las anotaciones de otros sys admins, tú incluso puedes mostrar el tuyo si te gusta.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *