web-dev-qa-db-fra.com

Comment extraire des fichiers dans S3 à la volée avec boto3?

J'essaie de trouver un moyen d'extraire des fichiers .gz dans S3 à la volée, ce n'est pas nécessaire de le télécharger localement, d'extraire puis de le repousser vers S3.

Avec boto3 + lambda, comment puis-je atteindre mon objectif?

Je n'ai vu aucune partie d'extrait dans le document boto3.

7
The One

Amazon S3 est un service de stockage. Il n'y a pas de capacité intégrée pour manipuler le contenu des fichiers.

Cependant, vous pouvez utiliser une fonction AWS Lambda pour récupérer un objet de S3, le décompresser, puis télécharger à nouveau le contenu. Cependant, veuillez noter qu'il y a une limite de 500 Mo d'espace disque temporaire pour Lambda, donc évitez de décompresser trop de données.

Vous pouvez configurer le compartiment S3 pour déclencher la fonction Lambda lorsqu'un nouveau fichier est créé dans le compartiment. La fonction Lambda aurait alors:

  • Utilisez boto3 (en supposant que vous aimez Python) pour télécharger le nouveau fichier
  • Utilisez la bibliothèque zipfile Python pour extraire les fichiers
  • Utilisez boto3 pour télécharger le ou les fichiers résultants

Exemple de code

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)
4
John Rotenstein

Vous pouvez utiliser BytesIO pour diffuser le fichier à partir de S3, l'exécuter via gzip, puis le rediriger vers S3 à l'aide de upload_fileobj pour écrire le BytesIO.

# python imports
import boto3
from io import BytesIO
import gzip

# setup constants
bucket = '<bucket_name>'
gzipped_key = '<key_name.gz>'
uncompressed_key = '<key_name>'

# 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

Assurez-vous que votre clé lit correctement:

# 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
7
Todd Jones