Объедините большие Azure большие двоичные объекты в один локальный файл, используя python - PullRequest
1 голос
/ 29 января 2020

Я использую python 3.6 с python SDK для Azure blob версии 1.5.0 и хотел бы объединить несколько Azure больших двоичных объектов в один локальный файл. Мне удалось это сделать, но когда я пытаюсь добавить блоб, превышающий объем памяти машины, операция завершается неудачей. Каков наилучший способ записи содержимого BLOB-объекта в файл кусками? Это мой код, который не работает с BLOB-объектами, размер которых превышает объем памяти машины

blob_files_names = blob_service.list_blob_names(container_name=blob_container_name, prefix=prefix)
with open(trg_path, 'wb') as file:
    for blob_file_name in blob_files_names:
        blob = blob_service.get_blob_to_bytes(container_name=blob_container_name, blob_name=blob_file_name)
        file.write(blob.content)

Ответы [ 2 ]

1 голос
/ 30 января 2020

Наконец-то мне удалось это сделать с помощью функции get_blob_to_path с открытым режимом добавления. Это работает, потому что эта функция записывает содержимое каждого блоба в конец файла кусками размером MAX_CHUNK_GET_SIZE

blob_files_names = blob_service.list_blob_names(container_name=blob_container_name, prefix=prefix)
for blob_file_name in blob_files_names:
    blob_service.get_blob_to_path(container_name=blob_container_name, blob_name=blob_file_name,
                                  file_path=trg_path, max_connections=1, open_mode='ab')
0 голосов
/ 29 января 2020

По моему опыту, звучит так, как будто есть несколько больших BLOB-объектов, размер которых превышает объем памяти вашего локального компьютера, поскольку используемая вами функция get_blob_to_bytes будет временно считывать содержимое BLOB-объектов в память для последующей записи.

Поэтому, пожалуйста, используйте другую функцию get_blob_to_stream вместо get_blob_to_bytes.

Вот мой пример кода, моя виртуальная среда основана на Python 3,7 с Azure Storage SDK через pip install azure-storage-blob==1.5.0.

from azure.storage.blob.baseblobservice import BaseBlobService

account_name = '<your account name>'
account_key = '<your account key>'

blob_service = BaseBlobService(account_name, account_key)

blob_container_name = '<your container name>'
prefix = '<your blob prefix>'
blob_files_names = blob_service.list_blob_names(container_name=blob_container_name, prefix=prefix)

# from io import BytesIO
from io import FileIO

trg_path = '<your target file path>'
# with open(trg_path, 'wb') as file:
with FileIO(trg_path, 'wb') as file:
    for blob_file_name in blob_files_names:
        #blob = blob_service.get_blob_to_bytes(container_name=blob_container_name, blob_name=blob_file_name)
        print(blob_file_name)
        # stream = BytesIO()
        blob_service.get_blob_to_stream(container_name=blob_container_name, blob_name=blob_file_name, stream=file)
        # file.write(stream.getbuffer())

Примечание: getbuffer() из stream из BytesIO выше не создаст копию значений в BytesIO буфер и, следовательно, не будет занимать большие объемы памяти.

...