0

Ich habe eine AWS-Lambda-Funktion, die jedes Mal ausgelöst wird, wenn eine CSV-Datei in s3-Bucket hochgeladen wird. Ich verwende serverless Rahmen mit Python 3.6 ist das Problem, dass ich diese Fehlermeldung bin immer habenTypeError: ein Byte-ähnliches Objekt ist erforderlich, nicht 'str' mit Serverless und Python3

a bytes-like object is required, not 'str': TypeError

Traceback (most recent call last):

File "/var/task/handler.py", line 33, in csvfile

fichier = obj['Body'].read().split('\n')

TypeError: a bytes-like object is required, not 'str'

ich einige der Forschung im Netz here tat, das Problem ist ich bin nicht die offene Methode verursachen mit der Datei gelesen wird so durch s3 Ereignis nicht wissen, wie es zu beheben

hier ist mein Code:

import logging 
import boto3 
from nvd3 import pieChart 
import sys 
import csv 


xdata = [] 
ydata = [] 
xdata1 = [] 
ydata1 = [] 


logger = logging.getLogger() 
logger.setLevel(logging.INFO) 

def csvfile(event, context): 

    s3 = boto3.client('s3')  
    # retrieve bucket name and file_key from the S3 event 
    bucket_name = event['Records'][0]['s3']['bucket']['name'] 
    file_key = event['Records'][0]['s3']['object']['key'] 
    logger.info('Reading {} from {}'.format(file_key, bucket_name)) 
    # get the object 
    obj = s3.get_object(Bucket=bucket_name, Key=file_key) 
    # get lines inside the csv 
    fichier = obj['Body'].read().split('\n') 
    #print lines 
    for ligne in fichier: 
     if len(ligne) > 1: 
      logger.info(ligne.decode()) 
      liste = ligne.split(',') 
      print(liste) 
      if liste[2] == 'ByCateg': 
       xdata.append(liste[4]) 
       ydata.append(liste[1]) 
      elif liste[2] == 'ByTypes': 
       xdata1.append(liste[4]) 
       ydata1.append(liste[1]) 

     print ' '.join(xdata) 

print('Function execution Completed') 

und hier ist mein serverless.yml Code:

service: aws-python # NOTE: update this with your service name 

provider: 
    name: aws 
    runtime: python3.6 
    stage: dev 
    region: us-east-1 
    iamRoleStatements: 
     - Effect: "Allow" 
      Action: 
       - s3:* 
       - "ses:SendEmail" 
       - "ses:SendRawEmail" 
       - "s3:PutBucketNotification" 
      Resource: "*" 

    functions: 
    csvfile: 
    handler: handler.csvfile 
    description: send mail whenever a csv file is uploaded on S3 
    events: 
     - s3: 
      bucket: car2 
      event: s3:ObjectCreated:* 
      rules: 
      - suffix: .csv 
+0

Bitte senden Sie das ganze Zurückverfolgungs –

+0

@brunodesthuilliers ich habe nur – ner

Antwort

3

Das Problem ist, dass

fichier = obj['Body'].read() 

gibt ein bytes Objekt, kein String. Dies liegt daran, dass die Codierung mehr als ein einzelnes Zeichen erfordern kann. Jetzt verwenden Sie split auf einem bytes Objekt, aber Sie können es nicht mit einer Zeichenfolge teilen, müssen Sie mit einem anderen bytes Objekt teilen. Speziell

sollten Sie Ihren Fehler beheben, aber je nachdem, was Sie erwarten, vielleicht ist die Entschlüsselung vor dem Split passender?

fichier = obj['Body'].read().decode("utf-8").split('\n') 
+0

ich das schon vor versuchen, erhalte ich diese Fehlermeldung: ‚str‘ Objekt hat kein Attribut ‚dekodieren‘: Attribut Traceback (jüngste Aufforderung zuletzt): Datei "/var/task/handler.py", Zeile 38, in csvfile logger.info (ligne.decode()) AttributError: 'str' Objekt hat kein Attribut 'decode'' – ner

+3

Das ist ein anderes Problem. Du hast 'fichier' in eine Zeichenkette mit der letzten Dekodierung umgewandelt, und ich vermute, woanders in deinem Code hast du es so übergeben wie es ist, aber ein Bytes Objekt wird erwartet - ich werde nicht für dich debuggen, der Stack sollte helfen. Sie können einfach überall mit Bytes bleiben - benutzen Sie die erste Version und verwenden Sie überall 'Bytes'. – kabanus

+0

danke dude, das macht es klarer – ner

Verwandte Themen