boto3 upload_fileobj загружает только 1000 объектов в папку S3

#python-3.x #amazon-web-services #amazon-s3 #boto3

Вопрос:

У меня более 1050 файлов json в папке s3, которые содержат поле ‘id’. Я перебираю эти файлы json, получая эти идентификаторы с помощью get_object. Я буду использовать эти идентификаторы и передавать вместе с URL-адресом, чтобы получить другой json-ответ, содержащий поле с указанием местоположения моментального снимка, то есть ссылку на скачивание файла. Я захватываю загруженный объект и записываю в местоположение s3, используя s3_client.upload_fileobj(байт-код (response.content), имя_загрузки, api_download_file_path имя_файла) все хорошо, но я получаю только 1000 csv-файлов в целевом местоположении s3 каждый раз, когда я это делаю, когда ожидаю 1050. Связано ли это с каким-либо ограничением на upload_fileobj.

полный код здесь

 result = s3_client.list_objects(Bucket=bucket_name, Prefix=api_target_read_path)
for res in result.get('Contents'):
    data = s3_client.get_object(Bucket=bucket_name, Key=res.get('Key'))
    contents = data['Body'].read().decode('utf-8')
    json_data = json.loads(contents)
    print(json_data['id'])
    json_id = json_data['id']
    geturl = inv_avail_get_api_url   json_id
    response = requests.get(geturl, headers=headers)
    print(response.text)
    durl = response.json()["response"]["snapshotLocation"]
    response = requests.get(durl)
    segments = durl.rpartition('/')
    file_name = str(segments[2]).split('?')[0]
    print(file_name)
    s3_client.upload_fileobj(BytesIO(response.content), bucket_name, api_download_file_path   file_name)
python
 

Ответ №1:

Вам необходимо использовать класс paginator, если вы пытаетесь получить более 1000 объектов одновременно, согласно документам:

Некоторые операции AWS возвращают неполные результаты и требуют последующих запросов для получения всего набора результатов. Процесс отправки последующих запросов для продолжения с того места, где остановился предыдущий запрос, называется разбивкой на страницы. Например, list_objects операция Amazon S3 возвращает до 1000 объектов одновременно, и вы должны отправлять последующие запросы с соответствующим маркером, чтобы получить следующую страницу результатов.

 s3 = boto3.client('s3')

paginator = s3.get_paginator('list_objects_v2')
pages = paginator.paginate(Bucket='bucket', Prefix='prefix')

for page in pages:
    for obj in page['Contents']:
        print(obj['Size'])

 

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

1. Я бы добавил, почему им нужно использовать класс paginator вместо простого предоставления примера кода

2. @ErmiyaEskandary, вы правы, немного описания всегда лучше. Обновил мой ответ и добавил некоторые подробности со ссылкой на документацию.

3. Замечательно 🙂 спасибо

4. Спасибо @SubhashisPandey сработал как по волшебству.