2013-04-12 5 views
18

Есть ли эффективный способ удалить все элементы с табуляции amazon dynamodb сразу. Я прошел через документы aws, но там показано удаление одного элемента.Удаление с amazon dynamodb

+0

Можете ли вы просто удалить таблицу? В противном случае это может помочь: http://stackoverflow.com/questions/9154264/what-is-the-recomended-way-to-delete-a-large-number-of-items-from-dynamodb – alfredaday

+0

Thanx alfredaday !! !! но каждый раз удалять и создавать одну и ту же таблицу создаст накладные расходы в моем приложении ... – rampuriyaaa

+1

Кроме того, создание таблицы не мгновенно. Обязательно не записывать в новую таблицу до тех пор, пока ее статус (прочитанный через describeTable) не будет «АКТИВНО» –

ответ

2

Если вы не можете отказаться от стола, вы должны использовать BatchWriteItem. Если все ваши записи находятся в пределах одного HashKey, вы можете использовать API запросов для извлечения записей, а затем удалить их по 25 элементов за раз. Если нет, вам, вероятно, придется сканировать.

В качестве альтернативы вы можете предоставить простую обертку вокруг AmazonDynamoDBClient (из официального SDK), которая собирает набор ключей Hash/Range, существующих в вашей таблице. Тогда вам не нужно будет запрашивать или сканировать элементы, вставленные после теста, так как у вас уже будет установлен 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<Key> примерно на Map<TableName, Set<Key>>. Вам нужно будет посмотреть свойство getTableName(), чтобы выбрать правильный Set для обновления.

Как только ваш тест заканчивается, захват содержимого таблицы и удаление должны быть простыми.

Одно окончательное предложение: используйте другую таблицу для тестирования, чем для вашего приложения. Создайте идентичную схему, но дайте таблице другое имя. Возможно, вам даже нужен другой пользователь IAM, чтобы ваш тестовый код не мог получить доступ к вашей рабочей таблице. Если у вас есть вопросы по этому поводу, не стесняйтесь открыть отдельный вопрос для этого сценария.

+1

подход может быть хорош для удаления тестовых данных, но он не идеален для реальных данных, особенно когда он масштабируется. Это похоже на сохранение и поддержание другого хранилища ключей над каждой таблицей DynamoDB. – ps2010

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); 
} 
+0

'scan' довольно дорого; однако использование 'query' не так чистое API-вызовов-wise – Neil

12

Выполните следующие действия:

  1. Make удалить запрос таблицы
  2. В ответ вы получите TableDescription
  3. Использование TableDescription снова создайте таблицу.

For step 1 and 2 click here

for step 3 click here

Вот что я в моем приложении.

+0

DeleteTableRequest deleteTableRequest = new DeleteTableRequest() .withTableName (" myTable "); УдалитьTableResult result = client.deleteTable (deleteTableRequest); –

4

Просто для записи, быстрое решение с пунктом за пунктом удаления в Python 3 (с использованием Boto3 и сканирования()): (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+) Для этого подход delete/recreate дешевле и эффективнее.

4

Как утверждает ihtsham, наиболее эффективным способом является удаление и повторное создание таблицы. Однако, если это непрактично (например, из-за сложной конфигурации таблицы, например триггеры Lambda), вот некоторые команды AWS CLI для удаления всех записей. Они нуждаются в программе jq для обработки JSON.

Удаление записей один-на-один (! Медленный), предполагая, что ваш стол называется my_table, ключ раздел называется partition_key, и ваш ключ сортировки (если таковые имеются) называется 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 

Удаление записи в партиях до 25 записей:

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 

Если вы начинаете видеть непустые UnprocessedItems ответов, ваша емкость записи превышена. Вы можете объяснить это, уменьшив размер партии. Для меня каждая партия занимает около секунды, чтобы отправить, поэтому с объемом записи 5 в секунду я установил размер партии в 5.