Другие ответы в этой теме относятся к 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)
В то время как прибегая к помощи я также видел некоторые ссылки, которые могут быть использовать, но я не пробовал:
код [smart_open] (https://github.com/piskvorky/smart_open) библиотека Python делает это (как для чтения, так и для записи). – Radim