Как разделить большой файл JSON в хранилище BLOB-объектов Azure на отдельные файлы для каждой записи с помощью Python? - PullRequest
0 голосов
/ 22 июня 2019

Я хочу иметь возможность разбить несколько больших файлов JSON в хранилище больших двоичных объектов (~ 1 ГБ каждый) на отдельные файлы (один файл на запись)

Я попытался использовать get_blob_to_stream из пакета Azure Python SDK, но япоявляется следующая ошибка:

AzureHttpError: Серверу не удалось аутентифицировать запрос.Убедитесь, что значение заголовка Авторизация сформировано правильно, включая подпись.

Чтобы проверить, я только что печатал текст, который был загружен из BLOB-объекта, и еще не пытался написать обратнок отдельным файлам JSON

with BytesIO() as document:
    block_blob_service = BlockBlobService(account_name=STORAGE_ACCOUNT_NAME, account_key=STORAGE_ACCOUNT_KEY)
    block_blob_service.get_blob_to_stream(container_name=CONTAINER_NAME, blob_name=BLOB_ID, stream=document)

    print(document.getvalue())

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

with BytesIO() as document:
    block_blob_service = BlockBlobService(account_name=STORAGE_ACCOUNT_NAME, account_key=STORAGE_ACCOUNT_KEY)
    block_blob_service.get_blob_to_stream(container_name=CONTAINER_NAME, blob_name=BLOB_ID, stream=document, start_range=0, end_range=100000)

    print(document.getvalue())

Кто-нибудь знает, что здесь происходит, или есть более эффективные подходы к разделению большого JSON?

Спасибо!

1 Ответ

0 голосов
/ 24 июня 2019

Это сообщение об ошибке «Серверу не удалось аутентифицировать запрос. Убедитесь, что значение заголовка авторизации сформировано правильно, включая подпись», которое вы обычно получаете, когда заголовок сформирован неправильно.вы получаете следующее, когда получаете эту ошибку:

<?xml version="1.0" encoding="utf-8"?>
<Error>
    <Code>AuthenticationFailed</Code>
    <Message>Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.
RequestId:096c6d73-f01e-0054-6816-e8eaed000000
Time:2019-03-31T23:08:43.6593937Z</Message>
    <AuthenticationErrorDetail>Authentication scheme Bearer is not supported in this version.</AuthenticationErrorDetail>
</Error>

, и решение этой проблемы заключается в добавлении нижнего заголовка:

x-ms-version: 2017-11-09

Но так как вы говорите, что это работает, когда выограничить размер, что означает, что вы должны писать свой код, используя чанк-подход.Вот что вы можете попробовать.

import io
import datetime
from azure.storage.blob import BlockBlobService

acc_name = 'myaccount'
acc_key = 'my key'
container = 'storeai'
blob = "orderingai2.csv"

block_blob_service = BlockBlobService(account_name=acc_name, account_key=acc_key)
props = block_blob_service.get_blob_properties(container, blob)
blob_size = int(props.properties.content_length)
index = 0
chunk_size =  104,858 # = 0.1meg don't make this to big or you will get memory error
output = io.BytesIO()


def worker(data):
    print(data)


while index < blob_size:
    now_chunk = datetime.datetime.now()
    block_blob_service.get_blob_to_stream(container, blob, stream=output, start_range=index, end_range=index + chunk_size - 1, max_connections=50)
    if output is None:
        continue
    output.seek(index)
    data = output.read()
    length = len(data)
    index += length
    if length > 0:
        worker(data)
        if length < chunk_size:
          break
    else:
      break

Надеюсь, это поможет.

...