web-dev-qa-db-fra.com

Comment lire un csv stocké dans S3 avec csv.DictReader?

J'ai du code qui récupère un objet AWS S3. Comment lire ce StreamingBody avec csv.DictReader de Python?

import boto3, csv

session = boto3.session.Session(aws_access_key_id=<>, aws_secret_access_key=<>, region_name=<>)
s3_resource = session.resource('s3')
s3_object = s3_resource.Object(<bucket>, <key>)
streaming_body = s3_object.get()['Body']

#csv.DictReader(???)
10
Jon

Le code serait quelque chose comme ceci:

import boto3
import csv

# get a handle on s3
s3 = boto3.resource(u's3')

# get a handle on the bucket that holds your file
bucket = s3.Bucket(u'bucket-name')

# get a handle on the object you want (i.e. your file)
obj = bucket.Object(key=u'test.csv')

# get the object
response = obj.get()

# read the contents of the file and split it into a list of lines

# for python 2:
lines = response[u'Body'].read().split()

# for python 3 you need to decode the incoming bytes:
lines = response['Body'].read().decode('utf-8').split()

# now iterate over those lines
for row in csv.DictReader(lines):

    # here you get a sequence of dicts
    # do whatever you want with each line here
    print(row)

Vous pouvez compacter cela un peu dans le code réel, mais j'ai essayé de le garder étape par étape pour afficher la hiérarchie des objets avec boto3.

Modifier Selon votre commentaire sur le fait d'éviter de lire tout le fichier en mémoire : Je n'ai pas rencontré cette exigence, donc je ne peux pas parler avec autorité, mais j'essaierais d'envelopper le stream afin que je puisse obtenir un itérateur de type fichier texte. Par exemple, vous pouvez utiliser la bibliothèque codecs pour remplacer la section d'analyse csv ci-dessus par quelque chose comme:

for row in csv.DictReader(codecs.getreader('utf-8')(response[u'Body'])):
    print(row)
23
gary