Как конвертировать CSV в JSON с Python на Амазонке лямбда? - PullRequest
0 голосов
/ 02 июля 2019

У меня есть лямбда-функция, которая пытается взять CSV-файл, который был загружен в корзину, преобразовать его в json и сохранить в другом.Вот мой код:

import json
import os
import boto3
import csv

def lambda_handler(event, context):
    for record in event['Records']:
        bucket = record['s3']['bucket']['name']
        file_key = record['s3']['object']['key']
        s3 = boto3.client('s3')
        csvfile = s3.get_object(Bucket=bucket, Key=file_key)
        csvcontent = csvfile['Body'].read().split(b'\n')

        data = []
        csv_file = csv.DictReader(csvcontent)
        print(csv_file)
        data = list(csv_file)

        os.chdir('/tmp')
        JSON_PATH = file_key[6:] + ".json"
        print(data)
        with open(JSON_PATH, 'w') as output:
          json.dump(data, output)
          bucket_name = 'xxx'
          s3.upload_file(JSON_PATH, bucket_name, JSON_PATH)

Проблема заключается в том, что, хотя при локальном тестировании этого файла на моем компьютере файл может быть преобразован в json, при запуске лямбда-функции я получаю следующую ошибку:

[ERROR] Error: iterator should return strings, not bytes (did you open the file in text mode?)
Traceback (most recent call last):
  File "/var/task/lambda_function.py", line 19, in lambda_handler
    data = list(csv_file)
  File "/var/lang/lib/python3.7/csv.py", line 111, in __next__
    self.fieldnames
  File "/var/lang/lib/python3.7/csv.py", line 98, in fieldnames
    self._fieldnames = next(self.reader)

Может кто-нибудь помочь мне понять, почему это происходит?Я давно пытаюсь найти решение и не понимаю, в чем проблема.Я ценю любую помощь, которую вы можете оказать

1 Ответ

1 голос
/ 02 июля 2019

Результат read() в s3.get_object() - это байты, а не строки. csv. DictReader() ожидает строки вместо байтов, и поэтому он терпит неудачу.

Вы можете декодировать результат read() в строки, используя функцию decode() с правильной кодировкой. Следующее будет исправлено:

изменить это

    csvcontent = csvfile['Body'].read().split(b'\n')

к этому

    csvcontent = csvfile['Body'].read().decode('utf-8')

Хороший способ устранить эти проблемы - использовать функцию type(), чтобы проверить тип переменной. В вашем случае вы легко можете найти проблему, попробовав print(type(csvcontent)) - это покажет, что csvcontent действительно имеет тип byte.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...