Автоматизируйте создание CSV-файлов, используя Boto3 S3 и Lambda - PullRequest
1 голос
/ 22 декабря 2019

Я выполняю лабораторную работу на веб-сайте LinuxAcademy.com. Название курса: Автоматизация AWS с помощью Lambda, Python и Boto3 , а конкретная лаборатория, с которой у меня возникают проблемы, - Лекция: Импорт CSVФайлы в DynamoDB .

В этой лабораторной работе мы загружаем файл .csv в S3, в этом конкретном сегменте генерируется событие S3, которое затем запускает Lambda-скрипт, показанный ниже:

import csv
import os
import tempfile

import boto3

dynamodb = boto3.resource('dynamodb')
table = dynamodb.Table('Movies')
s3 = boto3.client('s3')


def lambda_handler(event, context):

    for record in event['Records']:
        source_bucket = record['s3']['bucket']['name']
        key = record['s3']['object']['key']
        with tempfile.TemporaryDirectory() as tmpdir:
            download_path = os.path.join(tmpdir, key)
            s3.download_file(source_bucket, key, download_path)
            items = read_csv(download_file)

            with table.batch_writer() as batch:
                for item in items:
                    batch.put_item(Item=item)


def read_csv(file):
    items=[]
    with open(file) as csvfile:
        reader = csv.DictReader(csvfile)
        for row in reader:
            data = {}
            data['Meta'] = {}
            data['Year'] = int(row['Year'])
            data['Title'] = row['Title'] or none
            data['Meta']['Length'] = int(row['Length'] or 0)
            #data['Meta']['Length'] = int(row['Length'] or 0)
            data['Meta']['Subject'] = row['Subject'] or None
            data['Meta']['Actor'] = row['Actor'] or None
            data['Meta']['Actress'] = row['Actress'] or None
            data['Meta']['Director'] = row['Director'] or None
            data['Meta']['Popularity'] = row['Popularity'] or None
            data['Meta']['Awards'] = row['Awards'] == 'Yes'
            data['Meta']['Image'] = row['Image'] or None
            data['Meta'] = {k: v for k,
                            v in data['Meta'].items() if v is not None}

Загрузка CSV-файла на s3 вызывает лямбда-функцию. В строке 20 появляется сообщение об ошибке: items = read_csv(download_file)

Ошибка от AWS CloudWatch:

[ERROR] NameError: name 'download_file' is not defined
Traceback (most recent call last):
  File "/var/task/lambda_function.py", line 20, in lambda_handler
    items = read_csv(download_file)

1 Ответ

1 голос
/ 23 декабря 2019
s3.download_file(source_bucket, key, download_path)
items = read_csv(download_file)

В первой строке вызывается метод download_file() на клиенте Amazon S3 для загрузки файла на локальный диск.

Во второй строке вызывается функция read_csv() с передачей переменнойназывается download_file. Однако переменная с именем download_file не определена, поэтому вы получаете сообщение об ошибке.

При просмотре кода функция read_csv() ожидает открытия имени файла. Похоже, это доступно в переменной download_path, которая содержит локальный каталог и ключ. Поэтому измените его на:

items = read_csv(download_path)
...