web-dev-qa-db-fra.com

Lecture du contenu d'un fichier gzip à partir d'un AWS S3 dans Python

J'essaie de lire certains journaux d'un processus Hadoop que j'exécute dans AWS. Les journaux sont stockés dans un dossier S3 et ont le chemin suivant.

bucketname = nom clé = y/z/stderr.gz Ici Y est l'ID du cluster et z est un nom de dossier. Ces deux agissent comme des dossiers (objets) dans AWS. Le chemin complet est donc comme x/y/z/stderr.gz.

Maintenant, je veux décompresser ce fichier .gz et lire le contenu du fichier. Je ne veux pas télécharger ce fichier sur mon système veut enregistrer le contenu dans une variable python.

C'est ce que j'ai essayé jusqu'à présent.

bucket_name = "name"
key = "y/z/stderr.gz"
obj = s3.Object(bucket_name,key)
n = obj.get()['Body'].read()

Cela me donne un format qui n'est pas lisible. J'ai aussi essayé

n = obj.get()['Body'].read().decode('utf-8')

ce qui donne une erreur le codec utf8 ne peut pas décoder l'octet 0x8b en position 1: octet de démarrage invalide.

J'ai aussi essayé

gzip = StringIO(obj)
gzipfile = gzip.GzipFile(fileobj=gzip)
content = gzipfile.read()

Cela renvoie une erreur IOError: Pas un fichier compressé

Vous ne savez pas comment décoder ce fichier .gz.

Modifier - J'ai trouvé une solution. Nécessaire pour passer n dedans et utiliser BytesIO

gzip = BytesIO(n)
18
Kshitij Marwah

@Amit, j'essayais de faire la même chose pour tester le décodage d'un fichier, et j'ai fait exécuter votre code avec quelques modifications. J'ai juste dû supprimer la fonction def, le retour et renommer la variable gzip, car ce nom est utilisé.

import json
import boto3
from io import BytesIO
import gzip

try:
     s3 = boto3.resource('s3')
     key='YOUR_FILE_NAME.gz'
     obj = s3.Object('YOUR_BUCKET_NAME',key)
     n = obj.get()['Body'].read()
     gzipfile = BytesIO(n)
     gzipfile = gzip.GzipFile(fileobj=gzipfile)
     content = gzipfile.read()
     print(content)
except Exception as e:
    print(e)
    raise e
7
Levi

Vous pouvez utiliser AWS S3 SELECT Object Content pour lire le contenu gzip

S3 Select est une capacité Amazon S3 conçue pour extraire uniquement les données dont vous avez besoin d'un objet, ce qui peut considérablement améliorer les performances et réduire le coût des applications qui ont besoin d'accéder aux données dans S3.

Amazon S3 Select fonctionne sur les objets stockés au format Apache Parquet, les tableaux JSON et la compression BZIP2 pour les objets CSV et JSON.

Réf: https://docs.aws.Amazon.com/AmazonS3/latest/dev/selecting-content-from-objects.html

from io import StringIO
import boto3
import pandas as pd

bucket = 'my-bucket'
prefix = 'my-prefix'

client = boto3.client('s3')

for object in client.list_objects_v2(Bucket=bucket, Prefix=prefix)['Contents']:
    if object['Size'] <= 0:
        continue

    print(object['Key'])
    r = client.select_object_content(
            Bucket=bucket,
            Key=object['Key'],
            ExpressionType='SQL',
            Expression="select * from s3object",
            InputSerialization = {'CompressionType': 'GZIP', 'JSON': {'Type': 'DOCUMENT'}},
            OutputSerialization = {'CSV': {'QuoteFields': 'ASNEEDED', 'RecordDelimiter': '\n', 'FieldDelimiter': ',', 'QuoteCharacter': '"', 'QuoteEscapeCharacter': '"'}},
        )

    for event in r['Payload']:
        if 'Records' in event:
            records = event['Records']['Payload'].decode('utf-8')
            payloads = (''.join(r for r in records))
            try:
                select_df = pd.read_csv(StringIO(payloads), error_bad_lines=False)
                for row in select_df.iterrows():
                    print(row)
            except Exception as e:
                print(e)
3
rahulb

Lire le fichier d'extension Bz2 depuis aws s3 en python

import json
import boto3
from io import BytesIO
import bz2
try:
    s3 = boto3.resource('s3')
    key='key_name.bz2'
    obj = s3.Object('bucket_name',key)
    nn = obj.get()['Body'].read()
    gzipfile = BytesIO(nn)
    content = bz2.decompress(gzipfile.read())
    content = content.split('\n')
    print len(content)

except Exception as e:
    print(e)
1
amardip kumar

Actuellement, le fichier peut être lu comme

role = 'role name'
bucket = 'bucket name'
data_key = 'data key'
data_location = 's3://{}/{}'.format(bucket, data_key)
data = pd.read_csv(data_location,compression='gzip', header=0, sep=',', quotechar='"')
0
Anjala Abdurehman

Tout comme ce que nous faisons avec les variables, les données peuvent être conservées sous forme d'octets dans un tampon en mémoire lorsque nous utilisons les opérations Byte IO) du module io.

Voici un exemple de programme pour le démontrer:

mport io

stream_str = io.BytesIO(b"JournalDev Python: \x00\x01")
print(stream_str.getvalue())

La fonction getvalue() prend la valeur du tampon sous forme de chaîne.

Donc, la réponse @ Jean-FrançoisFabre est correcte, et vous devez utiliser

gzip = BytesIO(n)

Pour plus d'informations, lisez le document suivant:

https://docs.python.org/3/library/io.html

0
Reza Mousavi