Esiste un modo efficace per eliminare tutti gli elementi da una tabella dinamodb di Amazon contemporaneamente. Ho esaminato i documenti di aws, ma è stata visualizzata l'eliminazione di un singolo elemento.Eliminazione da amazon dynamodb
risposta
Si desidera utilizzare BatchWriteItem se non è possibile rilasciare la tabella. Se tutte le voci sono all'interno di un singolo HashKey, è possibile utilizzare l'API Query per recuperare i record e quindi eliminarli 25 elementi alla volta. In caso contrario, probabilmente dovrai eseguire la scansione.
In alternativa, è possibile fornire un semplice wrapper attorno allo AmazonDynamoDBClient
(dall'SDK ufficiale) che raccoglie un insieme di chiavi Hash/Intervallo presenti nella tabella. Quindi non avresti bisogno di Query o Scan per gli elementi che hai inserito dopo il test, dal momento che avresti già creato il Set. Che sarebbe simile a questa:
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
è una classe all'interno del DynamoDB SDK che accetta zero, uno, o due AttributeValue
oggetti nel costruttore di rappresentare una chiave hash o una chiave hash/intervallo. Supponendo che si tratti dei metodi equals
e , è possibile utilizzarli all'interno dello Set
che ho descritto. Se non lo fanno, dovrai scrivere la tua classe Key
.
Questo dovrebbe ottenere un set mantenuto per l'uso nei test. Non è specifico per una tabella, quindi potresti dover aggiungere un altro livello di raccolta se utilizzi più tabelle. Ciò cambierebbe Set<Key>
in qualcosa come Map<TableName, Set<Key>>
. Dovresti esaminare la proprietà getTableName()
per scegliere l'Set
corretto da aggiornare.
Una volta terminato il test, afferrare il contenuto della tabella e eliminarlo dovrebbe essere semplice.
Un ultimo suggerimento: utilizzare una tabella diversa per i test di quanto non si faccia per la propria applicazione. Crea uno schema identico, ma dai un nome diverso alla tabella. Probabilmente vorresti anche un altro utente IAM per impedire al tuo codice di test di accedere alla tua tabella di produzione. Se hai domande a riguardo, sentiti libero di aprire una domanda a parte per quello scenario.
l'approccio potrebbe essere utile per cancellare i dati del test, ma non è l'ideale per i dati reali, specialmente quando è ridimensionato. È come mantenere e gestire un altro datastore di chiavi sopra ogni tabella DynamoDB. – ps2010
DynamoDBMapper farà il lavoro in poche righe:
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);
}
'scan' è piuttosto costoso; tuttavia, l'uso di 'query' non è così semplice come l'API delle chiamate – Neil
effettuare le seguenti operazioni:
- Marchio eliminare richiesta tavolo
- Nella risposta si otterrà il TableDescription
- Utilizzando TableDescription crea nuovamente la tabella.
Questo è quello che faccio nella mia applicazione.
DeleteTableRequest deleteTableRequest = new DeleteTableRequest() .withTableName (" myTable "); Risultato DeleteTableResult = client.deleteTable (deleteTableRequest); –
Solo per la cronaca, una soluzione rapida con voce per voce Elimina nel Python 3 (usando Boto3 e scansione()): (Credentials devono essere impostati.)
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")
Ovviamente, questo non deve essere utilizzato per le tabelle con un sacco di oggetti . (100+) Per questo, l'approccio di eliminazione/ricreazione è più economico ed efficiente.
Come dice Ihtsham, il modo più efficace è eliminare e ricreare la tabella. Tuttavia, se ciò non è pratico (ad esempio a causa della configurazione complessa della tabella, come i trigger Lambda), ecco alcuni comandi AWS CLI per eliminare tutti i record. Richiedono il programma jq
per l'elaborazione JSON.
eliminazione di record uno ad uno (! Lento), supponendo che il tavolo si chiama my_table
, la vostra chiave di partizione si chiama partition_key
, e la vostra chiave di ordinamento (se presente) è chiamato sort_key
:
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
Eliminazione record in lotti di fino a 25 record:
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
Se si inizia a vedere non vuoti UnprocessedItems
risposte, la vostra capacità di scrittura è stato superato. Puoi tener conto di ciò riducendo la dimensione del batch. Per me, ogni batch impiega circa un secondo da inviare, quindi con una capacità di scrittura di 5 al secondo, imposto la dimensione del lotto a 5.
Puoi semplicemente eliminare la tabella? Altrimenti, questo potrebbe aiutare: http://stackoverflow.com/questions/9154264/questo-è-il-recomended-way-to-delete-a-large-number-of-items-from-dynamodb – alfredaday
Grazie alfredaday !! !! ma ogni volta che cancelli e crei una stessa tabella creerai un sovraccarico nella mia app ... – rampuriyaaa
Inoltre, la creazione di tabelle non è istantanea. Assicurati di non scrivere sulla nuova tabella fino a quando il suo stato (leggi tramite describeTable) è "ATTIVO" –