Двойной доступ к конфликту в таблице хранения Azure одновременно - PullRequest
0 голосов
/ 30 января 2019

Я запустил скрипт для извлечения данных из таблицы хранилища Azure (например, эта одна в качестве ссылки) и без проблем скопировал ее в другую таблицу из той же учетной записи хранения.

Теперь проблема возникла, когда я попытался получить доступ к этой последней таблице, чтобы выполнить некоторые вычисления и скопировать их в другую таблицу из той же учетной записи хранения.Этот скрипт возвратил следующую ошибку:

AzureConflictHttpError: Conflict
{"odata.error":{"code":"EntityAlreadyExists","message":{"lang":"en-US","value":"The specified entity already exists.\nRequestId:57d9b721-6002-012d-3d0c-b88bef000000\nTime:2019-01-29T19:55:53.5984026Z"}}}

В то же время, однако, код, который я выполнял ранее, также прекратил печатать ту же ошибку и не запустится снова, даже если код не запущен, возвращаяпредыдущая ошибка снова и снова.

Есть ли способ получить доступ к одному и тому же API в хранилище Azure несколько раз?

ОБНОВЛЕНИЕ

Добавление исходного кода, извините за то, что раньше этого не делалось.В основном два кода, которые я запускаю параллельно, одинаковы, но с разными фильтрами;на этом я беру данные из таблицы 1 (в которой есть строка в секунду), и я усредняю ​​эти числа в минуту, чтобы добавить строку в таблицу 2, а на другом сценарии я беру данные из этой таблицы2, чтобы усреднить эти строки в минуту до 5-минутной средней строки в другой Таблице 3, так что в основном изменяется несколько параметров, но код в основном такой же.

Будет третий сценарий, немного отличающийся от этих 2, но он будет принимать Таблицу 2 в качестве входного источника, выполнять другие вычисления и вставлять результаты в новую строку в минуту в будущей Таблице 4, поэтому вВ общем, моя идея состоит в том, чтобы иметь несколько записей в нескольких таблицах одновременно для создания новых конкретных таблиц.

import datetime
import time
from azure.storage.table import TableService, Entity

delta_time = '00:01:00'
retrieve_time = '00:10:00'
start_time = '08:02:00'
utc_diff = 3

table_service = TableService(account_name='xxx', account_key='yyy')

while True:
    now_time = datetime.datetime.now().strftime("%H:%M:%S") 
    now_date = datetime.datetime.now().strftime("%d-%m-%Y")
    hour = datetime.datetime.now().hour

    if hour >= 21:
        now_date = (datetime.datetime.now() + datetime.timedelta(days=1)).strftime("%d-%m-%Y")

    retrieve_max = (datetime.datetime.now() + datetime.timedelta(hours=utc_diff)+ datetime.timedelta(minutes=-10)).strftime("%H:%M:%S")

    start_diff = datetime.datetime.strptime(now_time, '%H:%M:%S') - datetime.datetime.strptime(start_time, '%H:%M:%S') + datetime.timedelta(hours=utc_diff)
    if start_diff.total_seconds() > 0:

        query = "PartitionKey eq '"+str(now_date)+"' and RowKey ge '"+str(retrieve_max)+"'"
        tasks=table_service.query_entities('Table1',query)
        iqf_0 = []

        for task in tasks:
            if task.Name == "IQF_0":
                iqf_0.append([task.RowKey, task.Area])  

        last_time = iqf_0[len(iqf_0)-1][0]
        time_max = datetime.datetime.strptime(last_time, '%H:%M:%S') - datetime.datetime.strptime(delta_time, '%H:%M:%S') #+ datetime.timedelta(hours=utc_diff)
        area = 0.0
        count = 0
        for i in range(len(iqf_0)-1, -1, -1):
            diff = datetime.datetime.strptime(last_time, '%H:%M:%S') - datetime.datetime.strptime(iqf_0[i][0], '%H:%M:%S')
            if diff.total_seconds() < 60:
                area += iqf_0[i][1]
                count += 1
            else: 
                break
        area_average = area/count

        output_row = Entity()
        output_row.PartitionKey = now_date
        output_row.RowKey = last_time
        output_row.Name = task.Name
        output_row.Area = area_average
        table_service.insert_entity('Table2', output_row)

        date_max = datetime.datetime.now() + datetime.timedelta(days=-1)
        date_max = date_max.strftime("%d-%m-%Y")
        query = "PartitionKey eq '"+str(date_max)+"' and RowKey ge '"+str(retrieve_max)+"'"
        tasks=table_service.query_entities('Table2',query)

        for task in tasks:
            diff = datetime.datetime.strptime(now_time, '%H:%M:%S') - datetime.datetime.strptime(task.RowKey, '%H:%M:%S') + datetime.timedelta(hours=utc_diff)
            print(i, datetime.datetime.strptime(now_time, '%H:%M:%S'), datetime.datetime.strptime(task.RowKey, '%H:%M:%S'), diff.total_seconds())
            if task.PartitionKey == date_max and diff.total_seconds()>0:
                table_service.delete_entity('Table2', task.PartitionKey, task.RowKey)

        time.sleep(60 - time.time() % 60)

1 Ответ

0 голосов
/ 30 января 2019

Похоже, вы запускали два кода для копирования данных в одну учетную запись хранилища Azure из Таблицы 1 в Таблицу 2 в Таблицу 3 одновременно.По моему опыту, проблема обычно возникала из-за одновременной одновременной записи записи данных (табличной сущности) или использования неправильного метода для существующей сущности, что является проблемой конкуренции ресурсов для записи.

ЭтоРаспространенная ошибка службы таблиц, вы можете найти ее на здесь .enter image description here

И есть документ Inserting and Updating Entities, в котором объясняются различия между операционными эффектами между функциями Insert Entity, Update Entity, Merge Entity, Insert Or Merge Entity и Insert Or Replace Entity.

Теперь ваш код не был передан нам.Учитывая все возможные случаи, есть три решения для устранения проблемы.

  1. Запуск двух кодов один за другим в порядке копирования данных между разными таблицами, а не одновременно.

  2. Используя правильную функцию для обновления данных для существующего объекта, вы можете сослаться на приведенный выше документ и аналогичный поток SO Добавить или заменить объект в хранилище таблиц Azure .

  3. Использование глобальной блокировки для уникального первичного ключа табличного объекта во избежание одновременной работы одного и того же табличного объекта в двух кодах.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...