【发布时间】:2019-06-23 02:09:31
【问题描述】:
我一直在运行一个脚本来从 Azure 存储表中检索数据(例如 this 一个作为参考)并将其从同一个存储帐户复制到另一个表中而没有问题。
现在,当我尝试访问后一个表以运行一些计算并将其从同一存储帐户复制到另一个表中时,问题就出现了。此脚本返回以下错误:
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"}}}
然而,与此同时,我之前运行的代码也停止打印相同的错误,即使没有代码运行也不会重新开始,一遍又一遍地返回之前的错误。
有什么方法可以多次访问 Azure 存储中的同一个 API?
更新
添加源代码,抱歉之前没有这样做。基本上我并行运行的两个代码是相同的,但过滤器不同;在这个我正在从表 1 中获取数据(每秒有一行),我正在平均每分钟将这些数字添加到表 2 中,在另一个脚本上我正在从这个表中获取数据2 将这些行每分钟平均到另一个表 3 中的 5 分钟平均行,所以基本上有一些参数改变但代码基本相同。
会有第三个脚本,与这两个略有不同,但会以表 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)
【问题讨论】:
-
您能否分享您的场景的更多细节?例如,您是否从 2 个应用程序访问 3 个表?您的应用程序如何读写这 3 个表(尤其是分区键和行键是如何组织的)?如果可能,您能否分享您的源代码,以便我们更好地理解您的问题?
-
嗨@ZhaoxingLu-Microsoft,刚刚添加了代码和更多详细信息。 PartitionKey 基本上是“dd-mm-yyyy”格式的日子,而 RowKeys 是“hh:mm:ss”格式的小时。我的意图是减少从表1到表2的行数(从T1平均60行到T2中的1行),以及从表2到表3的相同操作(从T2平均5行到T3中的1行) .
-
我没有仔细阅读代码,因为时间转换逻辑相当复杂且难以理解。您是否尝试过单独运行第一个脚本并查看错误是否仍然会发生?我怀疑单个脚本中的 while 循环导致了
EntityAlreadyExists错误,因为循环插入具有相同 partition key 和 row key 的实体不止一次.我建议您在将实体插入表之前编写一个日志以显示 分区键 和 行键,这可能会帮助您找到罪魁祸首。 -
我再次运行了第一个代码并且工作正常,可能由于缓存了一些信息,在冲突后它无法正常工作。所以你是说不能在同一个帐户的不同表中复制相同的分区键和行键?我会获取日志并更新帖子,谢谢!
-
不,同一个分区键和行键不能在同一张表中重复,但是跨表就可以了。但是,由于您看到 EntityAlreadyExists 错误,这意味着您的代码确实尝试将具有相同分区键和行键的实体插入到同一个表中。
标签: python azure azure-storage