【问题标题】:"Truncating" a DynamoDB Table Created via CloudFormation (SAM)“截断”通过 CloudFormation (SAM) 创建的 DynamoDB 表
【发布时间】:2019-10-30 04:17:27
【问题描述】:

我想在 DynamoDB 表中“截断”(删除所有项目)。我知道最有效的方法是删除表并重新创建它(名称、索引等)。但是,该表是 SAM-CloudFormation 部署的一部分。该表(按名称)也在应用程序的其他部分中被引用。

如果我删除并重新创建它,我可以使用以前的相同名称;但是,我认为这会导致问题,因为 (1) 删除不是立即的,并且 (2) ARN 会发生变化,这可能会对 CloudFormation 堆栈产生影响。

似乎应该有比蛮力方法更好的解决方案:遍历所有项目,一次删除一个(通过batch_writer 进行一些优化)。

我在这里查看了其他一些解决方案,但它们没有解决我的问题的“CloudFormation 堆栈的一部分”部分。

我什至自己为别人关于这个主题的问题提供了一个蛮力解决方案。

这是蛮力方法

import boto3

table = boto3.resource('dynamodb').Table('my-table-name')
scan = None

with table.batch_writer() as batch:
    count = 0
    while scan is None or 'LastEvaluatedKey' in scan:
        if scan is not None and 'LastEvaluatedKey' in scan:
            scan = table.scan(
                ProjectionExpression='id',
                ExclusiveStartKey=scan['LastEvaluatedKey'],
            )
        else:
            scan = table.scan(ProjectionExpression='id')

        for item in scan['Items']:
            if count % 5000 == 0:
                print(count)
            batch.delete_item(Key={'id': item['id']})
            count = count + 1

所需的最终状态是具有相同名称的 DynamoDB 表(之前充满项目),没有项目,并且仍然能够作为 CloudFormation 删除操作的一部分被销毁。

【问题讨论】:

  • 确保使用ConsistentRead: True进行扫描一致,否则如果在批量写入删除后扫描速度足够快,您可能会重复获得相同的项目。

标签: python amazon-web-services amazon-dynamodb amazon-cloudformation


【解决方案1】:

无论您将表创建为AWS::Serverless::SimpleTable 还是AWS::DynamoDB::Table,都没有现成的解决方案可以在保留其名称的同时使用 CloudFormation 清空它。

作为一般最佳实践,您不应命名由 CloudFormation 创建的 DynamoDB 表,而是让 CloudFormation 为资源分配名称。如果在您的设置中是这种情况,您可以简单地对需要“替换”资源的资源进行更改,例如临时添加本地二级索引,这将重新创建资源并根据它使用资源。

也就是说,在您的情况下,最好的方法可能是将您的蛮力方法包装在 CloudFormation custom resource 中,并将其包含在您的 CloudFormation 堆栈中。有了它,您可以一次截断表,或者根据您的自定义资源的实现,随时截断。

请记住,从 DynamoDB 表中删除所有项目可能需要很长时间,因此使用 Lambda 支持的自定义资源可能会遇到 Lambda 函数运行时的限制,具体取决于表中的项目数。如果表包含很多项目,它也可能变得相当昂贵。

【讨论】:

  • 我认为通过对模板进行两次更改来强制“截断”的想法非常有趣。 ¿ 像这样的事情你在想/建议吗? (关于“替换”选项)。使用boto's stack update 进行强制替换的更改(例如更改table's key schema),然后将其更改回原来的样子。
  • 是的,就是这样。但是,如果您依赖手动设置的表名称(正如您根据您的问题所做的那样),那将不起作用,因为这会导致 CloudFormation 尝试将由一个 ARN 标识的资源替换为由该 ARN 标识的另一个资源ARN(因为 CloudFormation 在删除旧资源之前创建新资源(请参阅docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/… 以供参考)。
  • 知道了。非常感谢。我想在创建它时使用该名称,但我看到了我在哪里写的。我正在考虑在删除之前动态获取名称(由 CF 设置),然后通过 API 创建具有相同名称的表。如果 arn 基于表名,这可能有效吗?
  • 对不起。我的意思是“我在创建时没有使用名称......”
猜你喜欢
  • 2019-09-12
  • 2021-11-17
  • 2018-12-03
  • 2017-08-10
  • 1970-01-01
  • 1970-01-01
  • 2019-03-23
  • 2022-08-22
  • 2021-03-30
相关资源
最近更新 更多