是否有任何有效的方法可以立即从亚马逊Dynamodb tabe中删除所有项目。我已经浏览了aws文档,但是它显示删除了单个项目。
答案 0 :(得分:13)
执行以下步骤:
这就是我在申请中所做的事情。
答案 1 :(得分:5)
DynamoDBMapper将在几行内完成工作:
AWSCredentials credentials = new PropertiesCredentials(credentialFile);
client = new AmazonDynamoDBClient(credentials);
DynamoDBMapper mapper = new DynamoDBMapper(this.client);
DynamoDBScanExpression scanExpression = new DynamoDBScanExpression();
PaginatedScanList<LogData> result = mapper.scan(LogData.class, scanExpression);
for (LogData data : result) {
mapper.delete(data);
}
答案 2 :(得分:5)
仅供记录,在 Python 3 中使用逐项删除的快速解决方案(使用 Boto3 和 scan()) : (Credentials需要设置。)
def delete_all_items(table_name):
# Deletes all items from a DynamoDB table.
# You need to confirm your intention by pressing Enter.
import boto3
client = boto3.client('dynamodb')
dynamodb = boto3.resource('dynamodb')
table = dynamodb.Table(table_name)
response = client.describe_table(TableName=table_name)
keys = [k['AttributeName'] for k in response['Table']['KeySchema']]
response = table.scan()
items = response['Items']
number_of_items = len(items)
if number_of_items == 0: # no items to delete
print("Table '{}' is empty.".format(table_name))
return
print("You are about to delete all ({}) items from table '{}'."
.format(number_of_items, table_name))
input("Press Enter to continue...")
with table.batch_writer() as batch:
for item in items:
key_dict = {k: item[k] for k in keys}
print("Deleting " + str(item) + "...")
batch.delete_item(Key=key_dict)
delete_all_items("test_table")
显然,这不应该用于包含批次的表格。 (100+)为此,删除/重新创建方法更便宜,更有效。
答案 3 :(得分:4)
如果您不能放弃表格,则需要使用BatchWriteItem。如果所有条目都在单个HashKey中,则可以使用查询API检索记录,然后一次删除25个项目。如果没有,你可能需要扫描。
或者,您可以在AmazonDynamoDBClient
(来自官方SDK)周围提供一个简单的包装器,用于收集表中存在的一组哈希/范围键。然后,您不需要查询或扫描测试后插入的项目,因为您已经构建了Set。这看起来像这样:
public class KeyCollectingAmazonDynamoDB implements AmazonDynamoDB
{
private final AmazonDynamoDB delegate;
// HashRangePair is something you have to define
private final Set<Key> contents;
public InsertGatheringAmazonDynamoDB( AmazonDynamoDB delegate )
{
this.delegate = delegate;
this.contents = new HashSet<>();
}
@Override
public PutItemResult putItem( PutItemRequest putItemRequest )
throws AmazonServiceException, AmazonClientException
{
contents.add( extractKey( putItemRequest.getItem() ) );
return delegate.putItem( putItemRequest );
}
private Key extractKey( Map<String, AttributeValue> item )
{
// TODO Define your hash/range key extraction here
// Create a Key object
return new Key( hashKey, rangeKey );
}
@Override
public DeleteItemResult deleteItem( DeleteItemRequest deleteItemRequest )
throws AmazonServiceException, AmazonClientException
{
contents.remove( deleteItemRequest.getKey() );
return delegate.deleteItem( deleteItemRequest );
}
@Override
public BatchWriteItemResult batchWriteItem( BatchWriteItemRequest batchWriteItemRequest )
throws AmazonServiceException, AmazonClientException
{
// Similar extraction, but in bulk.
for ( Map.Entry<String, List<WriteRequest>> entry : batchWriteItemRequest.getRequestItems().entrySet() )
{
String tableName = entry.getKey();
List<WriteRequest> writeRequests = entry.getValue();
for ( WriteRequest writeRequest : writeRequests )
{
PutRequest putRequest = writeRequest.getPutRequest();
if ( putRequest != null )
{
// Add to Set just like putItem
}
DeleteRequest deleteRequest = writeRequest.getDeleteRequest();
if ( deleteRequest != null )
{
// Remove from Set just like deleteItem
}
}
}
// Write through to DynamoDB
return delegate.batchWriteItem( batchWriteItemRequest );
}
// remaining methods elided, since they're direct delegation
}
Key
是DynamoDB SDK中的一个类,它在构造函数中接受零个,一个或两个AttributeValue
个对象来表示散列键或散列/范围键。假设equals
和hashCode
方法有效,您可以在我描述的Set
内使用。如果他们不这样做,您将必须编写自己的Key
课程。
这应该为您提供一个维护的Set,以便在您的测试中使用。它不是特定于表,因此如果您使用多个表,则可能需要添加另一个集合层。这会将Set<Key>
更改为Map<TableName, Set<Key>>
之类的内容。您需要查看getTableName()
属性以选择要更新的正确Set
。
测试完成后,抓取表格内容并删除应该很简单。
最后一个建议:使用与您的应用程序不同的表进行测试。创建一个相同的模式,但为表提供一个不同的名称。您可能甚至想要一个不同的IAM用户来阻止您的测试代码访问您的生产表。如果您对此有疑问,请随意为该方案打开一个单独的问题。
答案 4 :(得分:4)
正如ihtsham所说,最有效的方法是删除并重新创建表格。但是,如果这不可行(例如由于表的复杂配置,例如Lambda触发器),这里有一些AWS CLI命令可以删除所有记录。他们需要jq
程序进行JSON处理。
逐个删除记录(慢!),假设您的表名为my_table
,您的分区键称为partition_key
,并且您的排序键(如果有)被称为{{1 }}:
sort_key
批量删除最多25条记录的记录:
aws dynamodb scan --table-name my_table | \
jq -c '.Items[] | { partition_key, sort_key }' | \
tr '\n' '\0' | \
xargs -0 -n1 -t aws dynamodb delete-item --table-name my_table --key
如果您开始看到非空aws dynamodb scan --table-name my_table | \
jq -c '[.Items | keys[] as $i | { index: $i, value: .[$i]}] | group_by(.index / 25 | floor)[] | { "my_table": [.[].value | { "DeleteRequest": { "Key": { partition_key, sort_key }}}] }' | \
tr '\n' '\0' | \
xargs -0 -n1 -t aws dynamodb batch-write-item --request-items
响应,则表示您的写入容量已超出。您可以通过减少批量大小来解决这个问题。对我来说,每批需要大约一秒的时间来提交,所以写入容量为每秒5次,我将批量大小设置为5。
答案 5 :(得分:0)
您可以使用AWS Java SDK重新创建DynamoDB表
// Init DynamoDB client
AmazonDynamoDB dynamoDB = AmazonDynamoDBClientBuilder.standard().build();
// Get table definition
TableDescription tableDescription = dynamoDB.describeTable("my-table").getTable();
// Delete table
dynamoDB.deleteTable("my-table");
// Create table
CreateTableRequest createTableRequest = new CreateTableRequest()
.withTableName(tableDescription.getTableName())
.withAttributeDefinitions(tableDescription.getAttributeDefinitions())
.withProvisionedThroughput(new ProvisionedThroughput()
.withReadCapacityUnits(tableDescription.getProvisionedThroughput().getReadCapacityUnits())
.withWriteCapacityUnits(tableDescription.getProvisionedThroughput().getWriteCapacityUnits())
)
.withKeySchema(tableDescription.getKeySchema());
dynamoDB.createTable(createTableRequest);
答案 6 :(得分:0)
我使用以下javascript代码来做到这一点:
async function truncate(table, keys) {
const limit = (await db.describeTable({
TableName: table
}).promise()).Table.ProvisionedThroughput.ReadCapacityUnits;
let total = 0;
let lastEvaluatedKey = null;
do {
const qp = {
TableName: table,
Limit: limit,
ExclusiveStartKey: lastEvaluatedKey,
ProjectionExpression: keys.join(' '),
};
const qr = await ddb.scan(qp).promise();
lastEvaluatedKey = qr.LastEvaluatedKey;
const dp = {
RequestItems: {
},
};
dp.RequestItems[table] = [];
if (qr.Items) {
for (const i of qr.Items) {
const dr = {
DeleteRequest: {
Key: {
}
}
};
keys.forEach(k => {
dr.DeleteRequest.Key[k] = i[k];
});
dp.RequestItems[table].push(dr);
if (dp.RequestItems[table].length % 25 == 0) {
await ddb.batchWrite(dp).promise();
total += dp.RequestItems[table].length;
dp.RequestItems[table] = [];
}
}
if (dp.RequestItems[table].length > 0) {
await ddb.batchWrite(dp).promise();
total += dp.RequestItems[table].length;
dp.RequestItems[table] = [];
}
}
console.log(`Deleted ${total}`);
setTimeout(() => {}, 1000);
} while (lastEvaluatedKey);
}
(async () => {
truncate('table_name', ['id']);
})();
答案 7 :(得分:0)
在这种情况下,您可以删除表并创建一个新表。
示例:
from __future__ import print_function # Python 2/3 compatibility
import boto3
dynamodb = boto3.resource('dynamodb', region_name='us-west-2', endpoint_url="http://localhost:8000")
table = dynamodb.Table('Movies')
table.delete()