Другие ответы в этой теме относятся к boto, но S3.Object больше не повторяется в boto3.Итак, следующее НЕ РАБОТАЕТ, оно выдает сообщение об ошибке TypeError: 's3.Object' object is not iterable
:
s3 = boto3.session.Session(profile_name=my_profile).resource('s3')
s3_obj = s3.Object(bucket_name=my_bucket, key=my_key)
with io.FileIO('sample.txt', 'w') as file:
for i in s3_obj:
file.write(i)
В boto3 содержимое объекта доступно в S3.Object.get()['Body']
, что также не является итеративным, поэтому следующеевсе еще НЕ РАБОТАЕТ:
body = s3_obj.get()['Body']
with io.FileIO('sample.txt', 'w') as file:
for i in body:
file.write(i)
Таким образом, альтернативой является использование метода чтения, но он загружает в память объект ВСЕ S3, что при работе с большими файлами не всегда возможно:
body = s3_obj.get()['Body']
with io.FileIO('sample.txt', 'w') as file:
for i in body.read():
file.write(i)
Но метод read
позволяет передать параметр amt
, указывающий количество байтов, которые мы хотим прочитать из базового потока.Этот метод можно вызывать до тех пор, пока не будет прочитан весь поток:
body = s3_obj.get()['Body']
with io.FileIO('sample.txt', 'w') as file:
while file.write(body.read(amt=512)):
pass
При копании в botocore.response.StreamingBody
код один понимает, что базовый поток также доступен, поэтому мы могли бы выполнить итерацию следующим образом:
body = s3_obj.get()['Body']
with io.FileIO('sample.txt', 'w') as file:
for b in body._raw_stream:
file.write(b)
При поиске в Google я также видел некоторые ссылки, которые можно было бы использовать, но я не пробовал: