Ошибка Не найден файл при преобразовании файла, присутствующего в s3, с использованием boto3

  • У меня есть файлы csv, присутствующие в s3
  • Я могу распечатать имя корзины, ключ и содержимое файла
  • Но при преобразовании в json я получаю ошибку, файл не найден
  • Существует только один файл csv размером 1 КБ.

код ниже

import boto3
import csv
import json

# set up S3 connection
s3 = boto3.resource('s3')

my_bucket = s3.Bucket('csvfolder3')
# bucket_name = 'csvfolder3'

def lambda_handler(event, context):

    for file in my_bucket.objects.all():
        print(file.key)
        body = file.get()['Body'].read()
        print(body)
        with open(file.key, 'r') as csvfile: #####[ERROR] FileNotFoundError: [Errno 2] No such file or directory: 'data.csv'

            data = [row for row in csv.DictReader(csvfile)]
            json_data = json.dumps(data)
        s3.Object(my_bucket, 'file.json').put(Body=json_data)
open() ищет файл на локальном жестком диске. Предположительно, вы хотели вместо этого открыть файл в ведре s3?
John Gordon 30.03.2023 04:44

как вы ожидаете, что это сработает? вы перебираете my_bucket.objects.all() - все объекты в корзине S3. Вы работаете в функции AWS Lambda. Обратите внимание, что ваша функция Lambda волшебным образом не имеет всех (или каких-либо) ваших объектов S3, которые уже загружены и доступны для использования в локальном каталоге или в папке /tmp в этом случае.

rv.kvetch 30.03.2023 05:41

@rv.kvetch Существует только один файл csv размером 1 КБ.

sim 30.03.2023 08:11
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
3
63
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Когда у тебя есть:

body = file.get()['Body'].read()

Это уже загрузка содержимого файла (или объекта) в память в рамках функции AWS Lambda.

NB: следите за потребляемой памятью (МБ). При необходимости увеличьте объем памяти для функции Lambda.

Кроме того, я предполагаю, основываясь на документах, что ['Body'].read() возвращает объект bytes.

Итак, если у вас есть bytes, вы можете превратить его в строку с помощью:

bytes_data.decode()

Затем создайте файлоподобный объект, как и ожидает csv.DictReader, обернув приведенное выше:

StringIO(...)

Полный пример:

from __future__ import annotations

import csv
import json
from io import StringIO

byte_content = b"""
id,name,age,height,weight
1,Alice,20,62,120.6
2,Freddie,21,74,190.6
3,Bob,17,68,120.0
""".strip()

# set encoding if known
encoding = 'utf-8'

# decode bytes -> str
content = byte_content.decode(encoding)

# create file-like object
file = StringIO(content)

data: list[dict] = [row for row in csv.DictReader(file, delimiter = ",")]

json_data: str = json.dumps(data, indent=2)
print(json_data)

Результат:

[
  {
    "id": "1",
    "name": "Alice",
    "age": "20",
    "height": "62",
    "weight": "120.6"
  },
  {
    "id": "2",
    "name": "Freddie",
    "age": "21",
    "height": "74",
    "weight": "190.6"
  },
  {
    "id": "3",
    "name": "Bob",
    "age": "17",
    "height": "68",
    "weight": "120.0"
  }
]

если я хочу конвертировать напрямую без body = file.get()['Body'].read(), что мне делать? Также я получаю сообщение об ошибке #####[ERROR] FileNotFoundError: [Errno 2] Нет такого файла или каталога: 'data.csv'

sim 30.03.2023 08:09

Насколько я понимаю, невозможно преобразовать csv напрямую в json. причина в том, что ваши данные в формате CSV, и вы хотите, чтобы они были в формате JSON. Существует два подхода: 1) прочитать файл из S3 в виде байтов и обернуть его в файлоподобный объект или (2) прочитать файл из S3 в виде байтов, сохранить в локальную папку /tmp и передать фактический файловый объект с помощью open. Я бы сказал, что из этих двух подходов первый является наиболее простым. В любом случае вам нужно будет использовать csv.DictReader или что-то подобное для преобразования из CSV > dict > JSON.

rv.kvetch 31.03.2023 22:48

как упомянул @rv.kvetch, есть два способа конвертировать файл,

первый метод уже сделан им

добавление второго метода

import boto3
import csv
import json
import os

# set up S3 connection
s3 = boto3.client('s3')

def lambda_handler(event, context):
    # get bucket name and file name from event
    bucket_name = event['Records'][0]['s3']['bucket']['name']
    file_name = event['Records'][0]['s3']['object']['key']
    
    # download CSV file from S3
    csv_file_path = f'/tmp/{file_name}'
    s3.download_file(bucket_name, file_name, csv_file_path)
    
    # convert CSV data to JSON format
    with open(csv_file_path, 'r') as csvfile:
        data = [row for row in csv.DictReader(csvfile)]
        json_data = json.dumps(data)

    # upload JSON data to S3
    json_file_path = f'{os.path.splitext(file_name)[0]}.json'
    s3.put_object(Body=json_data, Bucket=bucket_name, Key=json_file_path)

    return {
        'statusCode': 200,
        'body': json.dumps('CSV to JSON conversion successful!')
    }

Другие вопросы по теме