简体   繁体   English

如何从Azure存储表中删除时间戳超过1天的所有实体?

[英]How to delete all entities with a timestamp more than 1 day old from Azure Storage Table?

Azure storage tables all have a timestamp column. Azure存储表都具有一个时间戳列。 Based on documentation here the listed way to delete from a storage table is to select an entity then delete it. 根据此处的文档,从存储表中删除的所列方法是选择一个实体,然后将其删除。

Does anyone know how to delete any entity from a storage table based on a datetime comparison on the timestamp value using code? 有谁知道如何根据使用代码对时间戳值进行的日期时间比较从存储表中删除任何实体?

EDIT: 编辑:

Based on the advice given I wrote the following code. 根据给出的建议,我编写了以下代码。 However, it throws a Bad Request exception on my table.ExecuteQuery(rangeQuery) call. 但是,它在我的table.ExecuteQuery(rangeQuery)调用上引发Bad Request异常。 Any advice? 有什么建议吗?

    StorageCredentials creds = new StorageCredentials(logAccountName, logAccountKey);
    CloudStorageAccount account = new CloudStorageAccount(creds, useHttps: true);

    CloudTableClient client = account.CreateCloudTableClient();

    CloudTable table = client.GetTableReference(LogTable);

    TableQuery<CloudQuerySummary> rangeQuery = new TableQuery<CloudQuerySummary>()
        .Where(TableQuery.GenerateFilterCondition("Timestamp", QueryComparisons.LessThan
        , DateTime.Now.AddHours(- DateTime.Now.Hour).ToString()));


    TableOperation deleteOperation;
    // Loop through the results, displaying information about the entity.
    foreach (CloudQuerySummary entity in table.ExecuteQuery(rangeQuery))
    {
        deleteOperation = TableOperation.Delete(entity);

        table.Execute(deleteOperation);
    }

EDIT 2 编辑2

Here is the final working code for anyone who chooses to copy/reference it. 这是选择复制/引用任何人的最终工作代码。

public void DeleteLogsNotFromToday()
{
    StorageCredentials creds = new StorageCredentials(logAccountName, logAccountKey);
    CloudStorageAccount account = new CloudStorageAccount(creds, useHttps: true);

    CloudTableClient client = account.CreateCloudTableClient();

    CloudTable table = client.GetTableReference(LogTable);

    TableQuery<CloudQuerySummary> rangeQuery = new TableQuery<CloudQuerySummary>()
        .Where(TableQuery.GenerateFilterConditionForDate("Timestamp", QueryComparisons.LessThan
        , DateTime.Now.AddHours(-DateTime.Now.Hour)));

    try
    {

        TableOperation deleteOperation;
        // Loop through the results, displaying information about the entity.
        foreach (CloudQuerySummary entity in table.ExecuteQuery(rangeQuery))
        {
            deleteOperation = TableOperation.Delete(entity);

            table.Execute(deleteOperation);
        }
    }
    catch (Exception ex)
    {
        throw;
    }

}

You will have to do a partition scan to do that, as entities are only indexed on their PartitionKey and RowKey. 由于实体仅在其PartitionKey和RowKey上进行索引,因此您将必须执行分区扫描。

In the tutorial link you posted, look at the section Retrieve a range of entities in a partition . 在您发布的教程链接中,查看检索分区中的一系列实体部分 Once you get the entities you want to delete, you will then execute a table operation to delete them. 获得要删除的实体后,将执行表操作将其删除。

If you don't want to delete them one by one, you can create a batch delete operation (provided all entities to delete have the same partition key). 如果您不想一个一个地删除它们,则可以创建一个批量删除操作(假设要删除的所有实体都具有相同的分区键)。 The link above also instructs how to construct a batch operation. 上面的链接还指示如何构造批处理操作。

Alternatively, if you do not want to do a table scan, you should store the date reference (for instance, storing the date in milliseconds as the RowKey) and then use that to filter the entities you need to delete based on a date-time comparison (something similar to THIS ) 或者,如果您不想进行表扫描,则应存储日期参考(例如,以毫秒为单位将日期存储为RowKey),然后使用该参考信息来过滤需要根据日期时间删除的实体比较(类似于THIS

UPDATE: I think the problem is in this line: DateTime.Now.AddHours(- DateTime.Now.Hour).ToString() 更新:我认为问题出在这行: DateTime.Now.AddHours(- DateTime.Now.Hour).ToString()

As from the documentation : 文档开始

The Timestamp property is a DateTime value that is maintained on the server side to record the time an entity was last modified Timestamp属性是一个DateTime值,在服务器端维护该值,以记录上一次修改实体的时间

You are trying to compare a DateTime property with a String. 您正在尝试将DateTime属性与String进行比较。 I'm no C# expert, but that does not look to me as a valid comparison. 我不是C#专家,但是我认为这不是有效的比较。

If you use Slazure this kind of job becomes easier, the following code should also work with the Light(free) edition. 如果使用Slazure,这种工作将变得更加容易,以下代码也应适用于Light(免费)版本。

using SysSurge.Slazure;
using SysSurge.Slazure.Linq;
using SysSurge.Slazure.Linq.QueryParser;

namespace TableOperations
{
    public class LogOperations 
    {
        public static void DeleteOldLogEntities()
        {
            // Get a reference to the table storage, example just uses the development storage
            dynamic storage = new QueryableStorage<DynEntity>("UseDevelopmentStorage=true");

            // Get a reference to the table named "LogTable"
            QueryableTable<DynEntity> logTable = storage.LogTable;
            var query = logTable.Where("Timestamp > @0", DateTime.UtcNow.AddDays(-1));

            // Delete all returned log entities
            foreach (var entity in query)
                logTable.Delete(entity.PartitionKey, entity.RowKey);
        }
    }
}

Full disclosure: I coded Slazure. 完全公开:我为Slazure编码。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM