Azure存储表[Python]-批处理不会失败

阿林·莱塞

我目前正在开发一个Python(2.7)应用程序,该应用程序通过Azure Python包使用Azure表存储服务。据我从Azure的REST API中了解到的那样,批处理操作会创建原子事务。因此,如果其中一项操作失败,则整个批处理都会失败,并且不会执行任何操作。

我遇到的问题如下:下面的方法通过“ rows”参数接收字典列表。有些具有ETag设置(从先前的查询中提供)。

如果设置ETag,请尝试合并操作。否则,尝试插入操作。由于存在多个可以修改同一实体的进程,因此需要通过merge_entity函数的“ if_match ”参数解决并发问题如果合并/插入操作是单个操作(不包括在批处理中),则系统将按预期工作,如果ETag不匹配,则会引发Exception。不幸的是,如果将它们包装在“ begin_batch” /“ commit_batch”调用中不会发生这种情况即使ETag不匹配,实体也会被合并(错误地)

我在下面提供了代码和使用的测试用例。还多次运行了一些具有相同结论的手动测试。

我不确定如何解决这个问题。我是在做错什么,还是Python包有问题?

使用的代码如下:

def persist_entities(self, rows):
    success = True
    self._service.begin_batch()        #If commented, works as expected (fails)
    for row in rows:
        print row
        etag = row.pop("ETag")
        if not etag:
            self._service.insert_entity(self._name,
                                        entity=row)
        else:
            print "Merging " + etag
            self._service.merge_entity(self._name,
                                       row["PartitionKey"],
                                       row["RowKey"],
                                       row, if_match=etag)
    try:            #Also tried with the try at the begining of the code
        self._service.commit_batch()       #If commented, works as expected (fails)
    except WindowsAzureError:
        print "Failed to merge"
        self._service.cancel_batch()
        success = False
    return success

使用的测试用例:

def test_fail_update(self):
        service = self._conn.get_service()
        partition, new_rows = self._generate_data()   #Partition key and list of dicts
        success = self._wrapper.persist_entities(new_rows)   #Inserts fresh new entity
        ok_(success)                                           #Insert succeeds
        rows = self._wrapper.get_entities_by_row(partition) #Retreives inserted data for ETag
        eq_(len(rows), 1)
        for index in rows:
            row = rows[index]
            data = new_rows[0]
            data["Count"] = 155                       #Same data, different value
            data["ETag"] = "random_etag"              #Change ETag to a random string
            val = self._wrapper.persist_entities([data])              #Try to merge
            ok_(not val)            #val = True for merge success, False for merge fail.
            #It's always True when operations in batch. False if operations out of batch 
            rows1 = self._wrapper.get_entities_by_row(partition)
            eq_(len(rows1), 1)
            eq_(rows1[index].Count, 123)
            break

    def _generate_data(self):
        date = datetime.now().isoformat()
        partition = "{0}_{1}_{2}".format("1",
                                         Stats.RESOLUTION_DAY, date)
        data = {
            "PartitionKey": partition,
            "RowKey": "viewitem",
            "Count": 123,
            "ETag": None
        }
        return partition, [data]
用户名

这是SDK(v0.8及更低版本)中的错误。我创建了一个问题并检入了修复程序。它将是下一发行版的一部分。您可以从git repo中点安装以测试修复。https://github.com/Azure/azure-sdk-for-python/issues/149

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章