Может ли AWS лямбда-функция работать напрямую с файлами на s3 или перемещается в / tmp / required? - PullRequest
1 голос
/ 01 марта 2020

Я пытаюсь написать AWS лямбда-функцию в Python, чтобы собрать набор CSV-файлов из корзины s3, объединить их, удалить дубликаты и записать результат обратно в s3. Файлы, которые я хочу прочитать, хранятся с префиксом / в папке на s3. В настоящее время я пытаюсь прочитать файлы по одному, используя следующее приложение:

resp = s3.list_objects_v2(Bucket='mybucket')
#getting all objects in the bucket in a list
for obj in resp['Contents']:
    keys.append(obj['Key'])
#filtering those that are parsed entries
files = [k[6:] for k in keys if 'links/links' in k]
#reading into combined list
for file in files:
    with open(file, 'r') as csvfile:
        reader = csv.reader(csvfile)
        links = links + list(reader)

В настоящее время я получаю следующую ошибку:

{
  "errorMessage": "[Errno 2] No such file or directory: 'links2020-02-27 14:59:49.933074.csv'",
  "errorType": "FileNotFoundError",
  "stackTrace": [
    "  File \"/var/task/handler.py\", line 21, in concatenatelinks\n    with open(file, 'r') as csvfile:\n"
  ]
}

В более ранней версии я не делал t нарезать имена файлов, что вызвало ту же ошибку. Так нужно ли загружать все файлы в / tmp / с чем-то вроде s3.meta.client.upload_file('/tmp/' + str(filename), bucket, 'fusedlinks/' + str(filename)), чтобы сделать их доступными для функции lamda, или есть более элегантное решение для этого?

1 Ответ

3 голосов
/ 01 марта 2020

Из ошибки кажется, что соглашение о названии файла неверно: links2020-02-27 14:59:49.933074.csv. Вам, вероятно, нужно экранировать « пробел » при чтении файла через клиент boto3.

Но для чтения файла есть два варианта, я лично предпочитаю вариант 2 (но зависит от использования памяти ):

  1. Один для использования файловой системы как / tmp

Вы можете сослаться на пример, как упомянуто в AWS Документация

Также AWS Lambda предоставляет / tmp размером 512 МБ на данный момент, вам нужно будет найти другое решение, если общий размер всех файлов превышает 512 МБ. См. AWS Лямбда-лимиты

Второй вариант - использовать буфер в памяти . Вы можете использовать: Python s BytesIo . Пример ниже:
    def load_from_s3(bucket, path):
        s3_resource = boto3.resource('s3')
        with BytesIO() as data:
            s3_resource.Bucket(bucket).download_fileobj(path, data)
            data.seek(0)
            # Do something with your data in file

...