Inne odpowiedzi w tym wątku są powiązane z boto, ale S3.Object nie jest już iterowalne w boto3. Więc Następujące nie działa, to wytwarza się komunikat TypeError: 's3.Object' object is not iterable
błędzie:
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)
W boto3 zawartość obiektu jest dostępny na S3.Object.get()['Body']
który nie jest iterable albo, więc dodaje się jeszcze nie działa:
body = s3_obj.get()['Body']
with io.FileIO('sample.txt', 'w') as file:
for i in body:
file.write(i)
więc alternatywą jest użycie metody odczytu, ale wczytuje całego obiektu S3 w pamięci, które po czynienia z dużymi plikami nie zawsze jest możliwość:
body = s3_obj.get()['Body']
with io.FileIO('sample.txt', 'w') as file:
for i in body.read():
file.write(i)
Jednak metoda read
pozwala na przekazanie parametru amt
określającego liczbę bajtów, które chcemy odczytać z podstawowego strumienia. Metoda ta może być wielokrotnie nazywany aż cały strumień został przeczytany:
body = s3_obj.get()['Body']
with io.FileIO('sample.txt', 'w') as file:
while file.write(body.read(amt=512)):
pass
kopanie w kodzie botocore.response.StreamingBody
zdamy sobie sprawę, że ogólny strumień dostępny jest również, więc możemy iteracyjne następująco:
body = s3_obj.get()['Body']
with io.FileIO('sample.txt', 'w') as file:
for b in body._raw_stream:
file.write(b)
Podczas googlowania ja również widziałem kilka linków, które mogą być użyte, ale nie próbowałem:
Sieć [smart_open] (https://github.com/piskvorky/smart_open) Biblioteka Pythona robi to (zarówno do czytania, jak i pisania). – Radim