Python:Azure 存储表在存在时无法插入批处理项

Posted

技术标签:

【中文标题】Python:Azure 存储表在存在时无法插入批处理项【英文标题】:Python: Azure Storage table failed to insert batch items when they are exists 【发布时间】:2018-12-10 19:09:43 【问题描述】:

我使用带有 python 的 Azure 存储表并尝试插入一批实体。第一次插入实体时,当它不存在于表中时,它工作得很快(如预期的那样)。在第二次插入相同的实体时,代码只是卡住了一分钟,并没有真正发生任何事情。

代码

这是我的批量插入:

acc_name = 'AccountName'
    acc_key = 'MyKey'
    table_name='MyTable'

    service = TableService(account_name=acc_name, account_key=acc_key)
    batch = TableBatch()
    batch.insert_entity(
        'PartitionKey': 'PARTITION1',
        'RowKey': "1",
        'someKey': 'key'
    )

    service.commit_batch(table_name, batch)

只需尝试运行此代码两次。第一次它会工作,第二次它会卡住一分钟并返回错误:

Client-Request-ID=a734f002-7dff-11e8-b587-28c63f6cb636 Retry policy did not allow for a retry: Server-Timestamp=Mon, 02 Jul 2018 13:55:29 GMT, Server-Request-ID=4168269a-0002-0073-640c-121de2000000, HTTP status code=202, 
Exception=The specified entity already exists.RequestId:4168269a-0002-0073-640c-121de2000000Time:2018-07-02T13:55:30.4994452Z.

测试 #1

我很确定这不是计划的行为,因为当我在 C# 中运行等效代码时,它会立即抛出异常:“索引 0 中的元素已经存在。”。这是有道理的...

测试 #2

我做的另一个测试是插入一个实体,而不是批量插入。在这种情况下,当实体已经在表中时,它只是抛出“已经存在”异常。哪个好。

我的环境

Windows 10、Python 3.6(64 位)、用于 python 的 azure-sdk(版本 3.0.0)。

有人可以确认这种行为吗?怎么办?

【问题讨论】:

【参考方案1】:

这是预期的行为。 insert_entity 操作是 Insert Entity REST API 操作的包装器,如果实体不存在则创建实体,否则将失败并出现 409 (Conflict) 错误。再次因为一个批处理操作失败,整个批处理操作失败。

您应该尝试使用Upsert 操作。您可以使用Insert or Replace EntityInsert or Merge Entity。这些操作将确保创建(如果不存在)或更新(如果存在)实体。 Python SDK中对应的操作应该分别是insert_or_replace_entityinsert_or_merge_entity

【讨论】:

Upsert 方法将更改不需要的现有行。当由于实体已经存在而批量插入失败时,它应该指定第一个插入失败的项目。预期消息:0:The specified entity already exists.。我找不到任何理由为什么这个无害的函数需要 60 秒才能执行(插入一行,表只包含一行)。对我来说,这似乎是一个错误。阅读更多:***.com/questions/40682971/…【参考方案2】:

正如@Gaurav Mantri 所说,只需将 insert_entity 替换为 insert_or_merge_entity:

acc_name = 'AccountName'
acc_key = 'MyKey'
table_name='MyTable'

service = TableService(account_name=acc_name, 
                       account_key=acc_key)
batch = TableBatch()
batch.insert_or_merge_entity(
    'PartitionKey': 'PARTITION1',
    'RowKey': "1",
    'someKey': 'key'
    )

service.commit_batch(table_name, batch)

【讨论】:

以上是关于Python:Azure 存储表在存在时无法插入批处理项的主要内容,如果未能解决你的问题,请参考以下文章

Azure 函数 - Powershell 和 Azure 存储表(插入或替换)

双向链表在循环python中某个节点结束后插入

Azure 存储:Blob:Python:获取指示符是不是存在 Blob

Azure 存储模拟器无法初始化,并显示“数据库 'AzureStorageEmulatorDb57' 不存在”

Azure 表存储在插入时支持空列字段

Azure 数据工厂到 Azure Blob 存储权限