Итак, я создаю сервис, который копирует файлы из S3 Bucket в папку Drive. Он запускает лямбду, когда объект создается в папке S3 Bucket /. Я беру файл (большой TXT-файл), копирую его содержимое «локально», чтобы иметь возможность загрузить его на диск через его API. Программа работает отлично, за исключением больших файлов. У меня заканчивается память:
[Errno 28] No space left on device: OSError
Traceback (most recent call last):
File "/var/task/lambda_function.py", line 67, in lambda_handler
raise e
File "/var/task/lambda_function.py", line 56, in lambda_handler
f.write(chunk[0:last_newline+1].decode('utf-8'))
OSError: [Errno 28] No space left on device
Вот код, который генерирует эту проблему, размер файла около 270 Мб. Тестирование запуска Lambda с настроенной памятью 2 ГБ.
obj = s3.get_object(Bucket = bucket,Key=key) #Getting the object that triggered the Lambda
fullpath="/tmp/"+key #To create a "local file" keeping its original name
os.chdir('/tmp')
f= open(fullpath,"w+") #Open the file to start writing in it.
body = obj['Body']
chunk_size = 1000000 * 10 #Reading it in chunks of ~10MB
newline = '\n'.encode()
partial_chunk = b''
while (True):
chunk = partial_chunk + body.read(chunk_size)
if chunk == b'':
break
last_newline = chunk.rfind(newline)
f.write(chunk[0:last_newline+1].decode('utf-8')) #Writing to the file (GETTING OUT OF MEMORY HERE)
f.flush()
# keep the partial line you've read here
partial_chunk = chunk[last_newline+1:]
f.close()
upload(parent,filename,key,fullpath)
И для загрузки я делаю:
upload():
...
drive_service = build('drive', 'v3', credentials=credenciales)
media_body1 = MediaFileUpload(fullpath, resumable=True,chunksize=1024 * 1024 * 5) #Using 5MB chunks
body1={'name':fullpath,'parents':[parent]}#,'media_body':content}
Filesubido = drive_service.files().create(body=body1, media_body=media_body1, supportsAllDrives='True')
response = None
while response is None:
time.sleep(5)
status, response = Filesubido.next_chunk()
if status:
print ("Uploaded "+ str(int(status.progress() * 100)))
print ("Upload Complete!")
Вещи, которые я пробовал:
- Расшифровывая тело файла прямо в память, скажем,
content=obj['Body'].read().decode('utf-8')
У лямбды не хватает памяти, поэтому я читаю ее порциями и сохраняю в файл вот так, но теперь у меня заканчивается «хранилище» (500 МБ макс., но размер файла составляет 270 МБ).
Вопросы:
- Можно ли загрузить файл в API накопителя БЕЗ сохранения файла локально на
/tmp
? * 1021 Lambda * - Любые другие идеи о том, как обработать файл, чтобы иметь возможность загрузить его с тем, что у меня есть?
Ура!