"Truncating" a DynamoDB Table Created via CloudFormation (SAM) 的翻译如下: 通过 CloudFormation(SAM)创建的 DynamoDB 表的 "Truncating"

4 浏览
0 Comments

"Truncating" a DynamoDB Table Created via CloudFormation (SAM) 的翻译如下: 通过 CloudFormation(SAM)创建的 DynamoDB 表的 "Truncating"

我想要在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删除操作的一部分被销毁。

0
0 Comments

问题出现的原因:无论是使用AWS::Serverless::SimpleTable还是AWS::DynamoDB::Table创建的DynamoDB表,在使用CloudFormation清空表的时候无法保留表的名称。

解决方法:通常最佳实践是不要为由CloudFormation创建的DynamoDB表指定名称,而是让CloudFormation为资源分配名称。在这种情况下,可以通过对资源进行需要“替换”的更改来清空表,比如临时添加一个本地二级索引,这将重新创建该资源并与依赖于它的资源一起使用。

然而,在这种情况下,最好的方法可能是将你的强制清空方法包装在一个CloudFormation自定义资源中,并将其包含在CloudFormation堆栈中。通过这种方式,可以在需要时清空表,具体取决于自定义资源的实现方式。

需要注意的是,删除DynamoDB表中的所有项目可能需要很长时间,因此使用基于Lambda的自定义资源可能会超出Lambda函数运行时间限制,具体取决于表中的项目数量。如果表中包含大量项目,这也可能会导致成本上升。

对于"truncate"的想法是通过对模板进行两次更改来强制执行,这个想法非常有趣。您是否考虑/建议类似这样的方法?(关于“替换”选项)。使用boto的堆栈更新来进行更改,以强制替换(例如更改表的键模式),然后将其改回原来的样子。

是的,这就是想法。然而,如果您依赖于手动设置的表名称(根据您的问题),这种方法不起作用,因为这将导致CloudFormation尝试用相同的ARN标识符替换由一个ARN标识的资源与由另一个ARN标识的资源(因为CloudFormation在删除旧资源之前创建新资源)。

明白了,非常感谢。我在创建时使用了名称,但这里我写错了。我考虑在删除之前动态获取名称(由CF设置),然后通过API创建一个具有相同名称的表。如果ARN基于表名称,这种方法可能管用吗?

抱歉,我是指“我没有在创建时使用名称...”

0