Proceso CSV línea por línea a partir de S3 usando python en Lambda

Estoy tratando de proceso .csv (30MB) archivo que está en el depósito de S3 con AWS Lambda (Python). Escribí mi código de python localmente en un archivo de proceso, que ahora está tratando de ejecutar utilizando Lambda. Tener un tiempo duro para leer el archivo línea por línea.

Por favor, hágamelo saber cómo puedo atravesar archivo línea por línea mediante boto3 o s3 métodos. Por favor me ayudan en el mismo a la mayor brevedad. Gracias

En Lambda:

s3 = boto3.client("s3")
        file_obj = event["Records"][0]
        filename=str(file_obj['s3']['object']['key'])
        #print('file name is :', filename)
        fileObj = s3.get_object(Bucket='sarapuri-weather-rawdata', Key=filename)
        file_content = fileObj["Body"].read().decode('utf-8')

Mi código Original:

import csv
import pandas as pd
import datetime
#from datetime import datetime,timedelta
import numpy as np
with open ('sample.csv', 'r') as file_name:

    csv_reader = csv.reader(file_name, delimiter=',')
    Time = []
    Latitude=[]
    Longitude= []
    Org_Units=[]
    Org_Unit_Type =[]
    Variable_Name=[]
    #New columns
    Year=[]
    Month= []
    Day =[]
    Celsius=[]
    Far=[]
    Conv_Units=[]
    Conv_Unit_Type=[]
    header = ['Time','Latitude', 'Longitude','Org_Units','Org_Unit_Type','Conv_Units','Conv_Unit_Type','Variable_Name']
    out_filename = 'Write' + datetime.datetime.now().strftime("%Y%m%d-%H%M%S") #need to rename based on the org file name

    with open(out_filename +'.csv', 'w') as csvFile:
        outputwriter = csv.writer(csvFile, delimiter=',')
        outputwriter.writerow(header)
        next(csv_reader, None)  # avoid hearder

        for row in csv_reader:
           # print(row)
            Time = row[0]
            Org_Lat=row[1]
            Org_Long=row[2]
            Org_Units=row[3]
            Org_Unit_Type =row[4]
            Variable_Name=row[5]
            # print(Time,Org_Lat,Org_Long,Org_Units,Org_Unit_Type,Variable_Name)

            if Org_Unit_Type == 'm s-1':
                Conv_Units =round(float(Org_Units) * 1.151,2)
                Conv_Unit_Type = 'miles'
            if Org_Unit_Type == 'm':
                Conv_Units =round(float(Org_Units) / 1609.344,2)
                 # print (Org_Units,Conv_Units)
                Conv_Unit_Type = 'miles'
            if Org_Unit_Type == 'Pa':
                Conv_Units =round(float(Org_Units) / 6894.757,2)
                Conv_Unit_Type = 'Psi'
                #print(type(Time))
            date_time_obj = datetime.datetime.strptime(Time, '%m-%d-%Y, %H:%M')
             #  Year = time.strptime(date_time_obj, "%B")
            #print(date_time_obj)
            f_row =[Time,Latitude,Longitude,Org_Units,Org_Unit_Type,Conv_Units,Conv_Unit_Type,Variable_Name]
            outputwriter.writerow(f_row)
csvFile.close()
print("done")

2 Respuestas

  • amittn
    4 de mayo de 2019

    Creo que esto debería funcionar la única cosa que usted necesita para comprobar es tu lambda necesidades de un papel con la política que tiene acceso de lectura en el s3. Inicialmente para la prueba iba a dar acceso completo a s3 a la lambda AmazonS3FullAccess

    {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Effect": "Allow",
                "Action": "s3:*",
                "Resource": "*"
            }
        ]
    }
    

    el código de python

    s3 = boto3.client('s3')
    def lambda_handler(event, context):
        # Get the object from the event and show its content type
        bucket = event['Records'][0]['s3']['bucket']['name']
        key = event['Records'][0]['s3']['object']['key'].encode('utf8')
        obj = s3.get_object(Bucket=bucket, Key=key)
        rows    = obj['Body'].read().split('\n')
        print("rows" + rows)
    
  • John Rotenstein
    4 de mayo de 2019

    En lugar de usar .read() para leer el objeto como un arroyo, usted podría encontrar que es más fácil para descargar el objeto para el almacenamiento local:

    s3_client = boto3.client('s3', region='ap-southeast-2')
    s3_client.download_file(bucket, key, '/tmp/local_file.csv')
    

    Usted puede utilizar su programa original para procesar el archivo.

    Una vez que haya terminado, asegúrese de eliminar el archivo temporal, ya que la AWS Lambda contenedor puede ser reutilizado y sólo hay 500 mb de espacio disponible en el disco.