"Truncating" a DynamoDB Table Created via CloudFormation (SAM) 的翻译如下: 通过 CloudFormation(SAM)创建的 DynamoDB 表的 "Truncating"
"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删除操作的一部分被销毁。
问题出现的原因:无论是使用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基于表名称,这种方法可能管用吗?
抱歉,我是指“我没有在创建时使用名称...”