es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Extrayendo archivos tar de un bucket de S3 a otro bucket de S3 utilizando Python

Necesitamos extraer el contenido de archivos zip y tar a otro bucket de S3.
Ya tenemos el código para extraer los archivos zip funcionando.
Necesitamos usar meta.client.upload_fileobj o meta.client.copy para utilizar subida múltiple o copia si es necesario.

def descomprimir_archivo(nombre_bucket_origen, nombre_archivo, nombre_bucket_destino):

    s3_resource = boto3.resource('s3')
    s3_client = boto3.client('s3')

    directorio_destino = nombre_archivo + '/'

    objeto_zip = s3_resource.Object(
        bucket_name=nombre_bucket_origen, key=nombre_archivo)

    buffer = BytesIO(objeto_zip.get()["Body"].read())

    with zipfile.ZipFile(buffer, mode='r', allowZip64=True) as z:
        for nombre_archivo in z.namelist():
            informacion_archivo = z.getinfo(nombre_archivo)

            s3_resource.meta.client.upload_fileobj(
                z.open(nombre_archivo),
                Bucket=nombre_bucket_destino,
                Key=f'{nombre_archivo}/{nombre_archivo}'
            )

No podemos hacer que la extracción de archivos tar funcione.

def descomprimir_tar(nombre_bucket_origen, nombre_archivo, nombre_bucket_destino):

    s3_resource = boto3.resource('s3')
    s3_client = boto3.client('s3')

    directorio_destino = nombre_archivo + '/'

    objeto_s3 = s3_client.get_object(Bucket=nombre_bucket_origen, Key=nombre_archivo)
    archivo_tar = objeto_s3['Body'].read()
    objeto_archivo = io.BytesIO(archivo_tar)

    with tarfile.open(fileobj=objeto_archivo, mode=('r:gz')) as z:
        for nombre_archivo in z.getmembers():
            s3_resource.meta.client.upload_fileobj(
                nombre_archivo, #z.open(nombre_archivo)
                Bucket=nombre_bucket_destino,
                Key=f'{nombre_archivo}/{nombre_archivo}'
            )

El problema es especificar el objeto del nombre de archivo en el comando meta.client.upload_fileobj.
Hemos probado con z.open(nombre_archivo)

Agradeceríamos mucho si alguien tiene alguna idea.

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    Parece que el problema con la función untar_file es que la variable filename que se utiliza en la llamada a upload_fileobj es un objeto TarInfo en lugar de los contenidos del archivo. Para solucionarlo, puedes utilizar el método extractfile del objeto TarFile para obtener un objeto similar a un archivo para cada archivo en el archivo tar.

    Aquí tienes una versión actualizada de la función untar_file:

    import tarfile
    
    def untar_file(source_bucketname, filename, target_bucketname):
        s3_resource = boto3.resource('s3')
        s3_client = boto3.client('s3')
        target_directory = filename + '/'
    
        s3_object = s3_client.get_object(Bucket=source_bucketname, Key=filename)
        tar_file = s3_object['Body'].read()
        file_object = io.BytesIO(tar_file)
    
        with tarfile.open(fileobj=file_object, mode='r:gz') as tar:
            for member in tar.getmembers():
                if member.isfile():
                    # Obtener un objeto similar a un archivo para el archivo actual en el archivo tar
                    file_obj = tar.extractfile(member)
                    # Utilizar el objeto similar a un archivo para cargar el archivo en S3
                    s3_resource.meta.client.upload_fileobj(
                        file_obj,
                        Bucket=target_bucketname,
                        Key=f'{target_directory}/{member.name}'
                    )
    

    En esta versión actualizada, utilizamos el método isfile de cada objeto TarInfo para omitir directorios y otras entradas que no sean archivos en el archivo tar. Luego, utilizamos el método extractfile para obtener un objeto similar a un archivo para el archivo actual, que podemos pasar a upload_fileobj para cargarlo en S3. Ten en cuenta que también modificamos el parámetro Key para utilizar la variable target_directory, que establecimos anteriormente como el nombre del directorio que contiene el archivo tar.

Comments are closed.