Azure 存储表逐行键删除

Posted

技术标签:

【中文标题】Azure 存储表逐行键删除【英文标题】:Azure storage table delete row by row key 【发布时间】:2016-09-09 02:52:18 【问题描述】:

我正在尝试仅通过 rowkey 值从 azure 存储过滤器中删除行。 但我没有看到删除操作有任何过载,我们只能使用行键进行过滤。对于具有特定行键的记录,是否有任何替代选项可以从 azure 存储表中删除行?

RemoveEntityByRowKey('123456');
public static void RemoveEntityByRowKey(string myRowKey)
        
            try
            
                CloudTable table = _tableClient.GetTableReference("MyAzureTable"); 
                       TableOperation delteOperation = TableOperation.Delete(myRowKey);
                table.Execute(delteOperation);
            
            catch (Exception ex)
            
                LogError.LogErrorToAzure(ex);
                throw;
            
        

【问题讨论】:

TableOperation.Delete is now deprecated 【参考方案1】:

要删除实体,您需要PartitionKeyRowKey (Delete Entity REST API)。所以你需要做的是首先获取匹配RowKey的实体。获取此实体后,您应该可以调用TableOperation.Delete,如答案中所述。

但是,不建议通过RowKey 获取实体,因为它会执行全表扫描。如果您的表尺寸很小,这可能不是问题,但如果您的表包含大量实体,这将是一个问题。此外,RowKeyPartition 中是唯一的,即在表中只能有一个具有PartitionKey/RowKey 组合的实体。换句话说,您可能在不同的Partitions 中拥有具有相同RowKey 的实体。因此,当您仅通过RowKey 获取实体时,您可能会得到多个实体。您需要确保删除正确的实体。

【讨论】:

漂亮而有趣的指针 Gaurav。基于行键删除记录会是一个坏主意吗?什么是最好的选择? 不确定您的表格是如何设计的,但最好的选择是您不必搜索实体。如果您知道实体的 PartitionKey 和 RowKey,则可以使用它来创建 TableEntity 的实例,然后删除该实体。 在我的情况下,分区键是时间滴答,它经常变化,不能用于查询。这就是我只能使用 rowkey 查询的原因。 了解...但请注意仅通过 RowKey 获取实体并不是最有效的方法。您提到您的 PartitionKey 是时间滴答。如果您的目标是删除特定时间段之间的实体,则可以包含 PartitionKey 范围并在这些范围内搜索 RowKey。这比仅在 RowKey 上搜索要好一些。 HTH。 如果要使用PartitionKey和RowKey删除实体,还需要指定ETag“*”,否则API会拒绝调用。在 Azure.Data.Tables 中,您可以使用 ETag.All 静态字段获取此类 ETag。【参考方案2】:

如果您知道 PartitionKey 和 RowKey,则无需检索整个实体即可将其删除。您可以按如下方式调整您的代码:

public static void RemoveEntityByRowKey(string myRowKey)

    try
    
        var entity = new YourEntity 
        
            PartitionKey = "partition",
            RowKey = myRowKey,
            ETag = "*"
        

        CloudTable table = _tableClient.GetTableReference("MyAzureTable"); 
        TableOperation delteOperation = TableOperation.Delete(entity);
        table.Execute(delteOperation);
    
    catch (Exception ex)
    
        LogError.LogErrorToAzure(ex);
        throw;
    
    

【讨论】:

【参考方案3】:

如果您的目标是 .NET Core,则需要使用 ExecuteQuerySegmentedAsync 方法来执行过滤条件查询。 ExecuteQuery 已弃用。

var cloudTableClient = _cloudStorageAccount.CreateCloudTableClient();
var myTable = cloudTableClient.GetTableReference("MyTable");
var query = new TableQuery<MyEntity>().Where(TableQuery.GenerateFilterCondition("RowKey", QueryComparisons.Equal, "myRowKey"));
var segment = await myTable.ExecuteQuerySegmentedAsync(query, null);
var myEntities = segment.Results;

【讨论】:

【参考方案4】:

按行是指记录吗?

TableOperation.Delete 接受一个表实体。见这里:https://msdn.microsoft.com/en-us/library/microsoft.windowsazure.storage.table.tableoperation.delete.aspx

为了删除该实体,您必须首先通过指定其Partition 键和/或Row 键来检索它。

在此处查看 TableQuery 类https://msdn.microsoft.com/en-us/library/microsoft.windowsazure.storage.table.tablequery_methods.aspx

一旦你检索到它,将它传递给 Delete 方法。

【讨论】:

你真的应该在 2 天内获得赏金奖励积分。您的回答是有用的指针。 不幸的是,这两个链接现在都是 404 如果您知道 PartionKey 和 RowKey,则无需先获取实体。使用TableOperation delete = TableOperation.Delete(new TableEntity(PartitionKey, RowKey) ETag = "*" )'【参考方案5】:

没有办法

TableOperation.Delete(String rowKey),

唯一的方法

public static TableOperation delete(final TableEntity entity)

在表操作中。详情见Get started with Azure Table storage using .NET

【讨论】:

什么??这似乎效率很低。您必须检索才能删除?必须有更好的方法。 @micahhoover 正确,您不需要需要检索到删除:您可以使用DynamicTableEntity 并仅提供PartitionKeyRowKey 值并将其传递给TableOperation.Delete - 但如果您只知道RowKey 而不知道PartitionKey,那么您需要进行某种形式的查询。【参考方案6】:

参考 Franks 的指针,我发布答案,以便对面临类似问题的其他人有用。

RemoveEntityByRowKey('123456');
public static void RemoveEntityByRowKey(string myRowKey)
        
            try
            
                CloudTable table = _tableClient.GetTableReference("MyAzureTable"); 

   TableQuery<myEntity> query = new TableQuery<myEntity>()
                   .Where(TableQuery.GenerateFilterCondition("RowKey", QueryComparisons.Equal, myRowKey));

                foreach (var item in table.ExecuteQuery(query))
                
                    var oper = TableOperation.Delete(item);
                    table.Execute(oper);                    
                 
            
            catch (Exception ex)
            
                LogErrorToAzure(ex);
                throw;
            
        

【讨论】:

虽然方法是正确的,但我认为您的设计可能不正确。在表查询中,您必须尽量避免表扫描(扫描几乎整个表,这是我相信您在这里所做的)或分区扫描(指定分区扫描和除 rowkey 之外的另一个键)。范围查询(指定分区和一定范围的rowkey)比较好,点查询是最好的。【参考方案7】:

mpl 是我的表行实体,需要从数据库中删除记录。 我已添加此答案以显示异步(带有结果检查)

           if (result)
            
                //delete the lead from the storage table
                TableOperation delRow = TableOperation.Delete(mpl);
                TableResult tr = await table.ExecuteAsync(delRow);
                if (((int)tr.HttpStatusCode) < 400)
                    log.LogInformation($"Table Record: mpl.RowKey deleted");
                else
                    log.LogError($"Table Record: mpl.RowKey NOT deleted");

            

【讨论】:

【参考方案8】:

Windows.Azure.Storage 命名空间现已弃用,取而代之的是 Azure.Data.Tables 命名空间。因此,TableOperation.Delete 方法也已弃用。您现在应该使用 TableClient 并且它是 DeleteEntity 方法:

TableClient tableClient = new TableClient(connectionString, Table);
tableClient.DeleteEntity(PartitionKey, RowKey);

如果您也愿意,还有异步版本DeleteEntityAsync

【讨论】:

以上是关于Azure 存储表逐行键删除的主要内容,如果未能解决你的问题,请参考以下文章

python读取excel一例-------从工资表逐行提取信息

Azure 表存储查询性能

如何降低 Azure 表存储延迟

Azure 表存储:按顺序排列

Azure 流分析分区键列在表存储中重复

向 Azure 表存储中的同一键添加多个值