使用Python删除DynamoDB中的所有项。

10 浏览
0 Comments

使用Python删除DynamoDB中的所有项。

我如何使用Python(boto3)从DynamoDB中删除所有项目?

我正在尝试这样做:

scan = table.scan()
with table.batch_writer() as batch:
  for each in scan['Items']:
    batch.delete_item(Key=each)

但是给我这个错误:

botocore.exceptions.ClientError: 调用BatchWriteItem操作时发生错误(ValidationException):提供的键元素与模式不匹配

0
0 Comments

问题:如何使用Python从DynamoDB中删除所有项目?

原因:当尝试截断一个大表(或者一个拥有大型项目的较小表)时,可能无法在第一次调用中获取所有记录。代码中使用了批处理写入器(batch_writer),并且在循环中使用了扫描(scan)操作来获取所有项目。

解决方法:

1. 导入boto3库:使用import boto3导入boto3库。

2. 定义表和ID:根据实际情况,定义表名和ID。

3. 创建DynamoDB资源:使用boto3.resource('dynamodb')创建DynamoDB资源。

4. 使用批处理写入器(batch_writer):使用with table.batch_writer() as batch:来创建批处理写入器。

5. 使用循环删除项目:使用循环来扫描表中的项目,并逐个删除。在循环中,首先检查是否已经执行过扫描操作,并且该操作返回了最后一个评估键(LastEvaluatedKey)。如果有最后一个评估键,则使用table.scan(ProjectionExpression=ID, ExclusiveStartKey=scan['LastEvaluatedKey'])进行下一次扫描。否则,使用table.scan(ProjectionExpression=ID)进行第一次扫描。然后,使用batch.delete_item(Key={ID: item[ID]})删除项目。

6. 输出进度计数器:为了方便人类查看操作进度,每删除5000个项目时,输出一个进度计数器。

7. 引用其他来源:根据回答中的评论,如果出现找不到'LastEvaluatedKey'的错误,可以根据提供的链接查找解决方法。

完整代码如下:

import boto3
TABLE = ...
ID = ...
table = boto3.resource('dynamodb').Table(TABLE)
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

以上就是使用Python从DynamoDB中删除所有项目的方法。如果遇到找不到'LastEvaluatedKey'的错误,可以参考提供的链接寻找解决方法。

0
0 Comments

问题的出现原因:需要使用Python删除DynamoDB中的所有项。

解决方法:使用批量写入操作进行删除。

以下是解决该问题的代码:

scan = table.scan()
with table.batch_writer() as batch:
    for each in scan['Items']:
        batch.delete_item(
            Key={
                'uId': each['uId'],
                'compId': each['compId']
            }
        )

这段代码会扫描整个表,并使用批量写入操作删除每个项。通过指定每个项的键(uId和compId),可以确保删除正确的项。

需要注意的是,由于分页的存在,可能无法一次性删除较大表中的所有项。但是,根据作者提供的信息,该表是按天进行删除的,因此不需要进行分页删除,可以直接使用上述代码删除所有项。

0
0 Comments

原因:该问题的原因是需要删除DynamoDB表中的所有项目,但是由于表中有许多全局二级索引(GSI)或触发器事件与表关联,所以不想重新关联这些索引或事件。

解决方法:下面的Python脚本将迭代扫描以处理大型表(每个扫描调用将返回1MB的键),并使用批处理函数来删除表中的所有项目。代码中使用了boto3库来连接DynamoDB,通过调用`truncateTable`函数并传递表名来删除所有项目。

import boto3
dynamo = boto3.resource('dynamodb')
def truncateTable(tableName):
    table = dynamo.Table(tableName)
    #get the table keys
    tableKeyNames = [key.get("AttributeName") for key in table.key_schema]
    #Only retrieve the keys for each item in the table (minimize data transfer)
    projectionExpression = ", ".join('#' + key for key in tableKeyNames)
    expressionAttrNames = {'#'+key: key for key in tableKeyNames}
    counter = 0
    page = table.scan(ProjectionExpression=projectionExpression, ExpressionAttributeNames=expressionAttrNames)
    with table.batch_writer() as batch:
        while page["Count"] > 0:
            counter += page["Count"]
            # Delete items in batches
            for itemKeys in page["Items"]:
                batch.delete_item(Key=itemKeys)
            # Fetch the next page
            if 'LastEvaluatedKey' in page:
                page = table.scan(
                    ProjectionExpression=projectionExpression, ExpressionAttributeNames=expressionAttrNames,
                    ExclusiveStartKey=page['LastEvaluatedKey'])
            else:
                break
    print(f"Deleted {counter}")
truncateTable("YOUR_TABLE_NAME")

这段代码是当前答案中最好的解决方法。它具有以下优点:1)通过使用批处理操作来提高运行速度,2)通过使用ExpressionAttributeNames来正确处理具有无效字符的键,3)自动发现键名,非常方便。

需要注意的是,如果在代码中添加了扫描的过滤器,可能会导致代码停止工作。因为在这种情况下,当`page["Count"] == 0`时,仍然可能存在下一页。

如果在运行代码时出现以下错误:`botocore.exceptions.ClientError: An error occurred (ValidationException) when calling the Scan operation: ExpressionAttributeNames contains invalid key: Syntax error; key: "#url_id-process-index"`,请检查代码中的表名和键名是否正确,并确保它们符合DynamoDB的命名规则。

0