Удаление из Amazon Dynamodb

Есть ли какой-либо эффективный способ удалить все элементы из вкладки amazon Dynamodb сразу. Я просмотрел документы aws, но там показано удаление одного элемента.


person rampuriyaaa    schedule 12.04.2013    source источник
comment
Вы можете просто удалить таблицу? В противном случае это может помочь: stackoverflow.com/questions/9154264/   -  person alfredaday    schedule 12.04.2013
comment
Спасибо, alfredaday !!!! но постоянное удаление и создание одной и той же таблицы приведет к накладным расходам в моем приложении ...   -  person rampuriyaaa    schedule 12.04.2013
comment
Кроме того, создание таблицы не происходит мгновенно. Будьте уверены, что не записываете в новую таблицу, пока ее статус (чтение с помощью describeTable) не станет АКТИВНЫМ.   -  person Zim-Zam O'Pootertoot    schedule 12.04.2013
comment
Не могли бы вы подробнее описать свой вариант использования? Какое событие в вашем приложении требует усечения таблицы? Отредактируйте вопрос своими ответами, так как они относятся к любому ответу, который вы получите.   -  person Steven Hood    schedule 13.04.2013
comment
Привет, Стивен !!!! на самом деле я тоже использую Dynamodb для тестирования, поэтому после запуска тестового примера db загружается с нежелательными записями, которые мне нужно удалить, чтобы его можно было использовать в приложении. Таким образом, удаление всей таблицы - плохая идея ....   -  person rampuriyaaa    schedule 13.04.2013


Ответы (8)


Если вы не можете отбросить стол. Если все ваши записи находятся в одном 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 методы работают, вы можете использовать in в Set, описанном мною. Если они этого не сделают, вам придется написать свой собственный Key класс.

Это должно дать вам поддерживаемый набор для использования в ваших тестах. Это не относится к таблице, поэтому вам может потребоваться добавить еще один уровень коллекции, если вы используете несколько таблиц. Это изменит Set<Key> на что-то вроде Map<TableName, Set<Key>>. Вам нужно будет посмотреть на свойство getTableName(), чтобы выбрать правильный Set для обновления.

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

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

person Steven Hood    schedule 13.04.2013
comment
Этот подход может быть хорош для удаления тестовых данных, но он не идеален для реальных данных, особенно когда они масштабируются. Это похоже на хранение и поддержку другого хранилища ключей над каждой таблицей DynamoDB. - person ps2010; 21.01.2016

Сделайте следующие шаги:

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

Для шагов 1 и 2 нажмите здесь

, чтобы перейти к шагу 3, нажмите здесь

Это то, что я делаю в своем приложении.

person Ihtsham Minhas    schedule 23.09.2015
comment
DeleteTableRequest deleteTableRequest = новый DeleteTableRequest () .withTableName (myTable); DeleteTableResult result = client.deleteTable (deleteTableRequest); - person Víctor Romero; 18.01.2016
comment
Как это будет работать, если имена таблиц должны быть уникальными, а запрос на удаление таблицы не является немедленным? AWS переводит таблицу в состояние удаления, и на удаление требуется некоторое время. - person Connor Clark; 28.07.2018

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);
}
person Nicolas M    schedule 09.01.2014
comment
scan довольно дорого; однако использование query не так чисто с точки зрения вызовов API - person Neil; 28.05.2016

Как говорит Ихтшам, наиболее эффективный способ - удалить и заново создать таблицу. Однако, если это нецелесообразно (например, из-за сложной конфигурации таблицы, такой как триггеры Lambda), вот несколько команд интерфейса командной строки AWS для удаления всех записей. Им требуется программа 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.

person Trevor Robinson    schedule 14.11.2016

Просто для записи, быстрое решение с поэтапным удалением в Python 3 (с использованием Boto3 и scan ()): (Необходимо указать учетные данные.)

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+) Для этого подход удаления / воссоздания дешевле и эффективнее.

person Attila Tanyi    schedule 21.01.2016

Вы можете воссоздать таблицу DynamoDB с помощью AWS Java SDK

// 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);
person Rafal Enden    schedule 23.08.2018

Для этого я использую следующий код 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']);
})();
person Mike Shauneu    schedule 19.01.2019

В этом случае вы можете удалить таблицу и создать новую.

Пример:

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()
person Sharhabeel Hamdan    schedule 16.01.2020