Загрузка нескольких файлов из определенного «подкаталога», AWS S3 с boto3 и Python 3.7

#python #amazon-web-services #amazon-s3 #boto3

#python #amazon-веб-сервисы #amazon-s3 #boto3

Вопрос:

 import boto3
import os 

client = boto3.client('connect')

s3 = boto3.resource(
    service_name='s3',
    region_name='us-west-2',
    aws_access_key_id=aws_access_key_id,
    aws_secret_access_key=aws_secret_access_key
)

   
for my_bucket_object in s3.Bucket("my_bucket").objects.filter(Prefix="user/folder/"):
    s3.Object(my_bucket_object.bucket_name, my_bucket_object.key).download_file(f'./aws/{my_bucket_object.key}')
 
  1. Без итерации, но похожего кода я могу успешно загружать отдельные файлы.
  2. Без загрузки печать ключей корзины показывает обычные результаты

Однако, когда я перебираю несколько файлов и использую ключ в качестве входных данных для download_file, я получаю следующее сообщение об ошибке. Имя целевого ключа, похоже, меняется?

Ошибка FileNotFoundError: [Ошибка 2] Нет такого файла или каталога: ‘./aws/user/ folder .7g4DBa9A’

У меня есть следующие два вопроса:

  1. Как я могу предотвратить это и загрузить файлы?
  2. Есть ли способ отделить имена файлов от «подкаталогов» (я понимаю, что AWS их не использует, но ключи содержат имена каталогов / файлов, разделенные только символом «/», я хотел бы разделить их для сохранения)

=========================================================================== Нашел ответ благодаря комментарию Марчина. После итеративной печати всех выходных данных казалось, что первой была «папка», которая при загрузке переводилась на странные имена.
ie.
пользователь / папка /
пользователь / папка / файл1
пользователь / папка / файл2
и т.д.

Таким образом, игнорирование этой первой итерации позволило решить проблему.

 for obj in my_bucket.objects.filter(Prefix=prefix):
       
    output_file = obj.key.split('/')[-1]

    if output_file == "":
        continue
    else:
        s3.Object(bucket_name=my_bucket.name, key=my_bucket_object.key).download_file(arbitrary output path)
 

Ответ №1:

есть ли способ отделить имена файлов от «подкаталогов»

Вы можете разделить ключ на / и взять последний элемент, прежде чем делать download_file :

 output_file = my_bucket_object.key.split('/')[-1]
s3.Object(my_bucket_object.bucket_name, my_bucket_object.key).download_file(f'./aws/output_file')
 

Комментарии:

1. Спасибо! Вопрос 2 был ответом. Я все еще застрял на вопросе 1 (для всех, кто просматривает эту тему)

2. @Shaner Вы предотвращаете это, указав правильный путь сохранения, который является вопросом 2.

3. Я нашел ответ косвенно через ваш первый комментарий. Спасибо!