20

Amazon dynamodb テーブルからすべてのアイテムを一度に削除する効率的な方法はありますか? aws ドキュメントを確認しましたが、単一のアイテムの削除が示されています。

4

8 に答える 8

6

ihtsham が言うように、最も効率的な方法は、テーブルを削除して再作成することです。ただし、それが実用的でない場合 (例: Lambda トリガーなどのテーブルの複雑な構成のため)、すべてのレコードを削除するための AWS CLI コマンドを次に示します。jqJSON 処理用のプログラムが必要です。

my_tableテーブルを、パーティション キーpartition_keyを 、ソート キー (存在する場合) を と仮定して、レコードを 1 つずつ (遅い!) 削除します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応答が表示され始めた場合は、書き込み容量を超えています。これは、バッチ サイズを小さくすることで解決できます。私の場合、各バッチの送信には約 1 秒かかるため、1 秒あたり 5 の書き込み容量で、バッチ サイズを 5 に設定します。

于 2016-11-14T16:14:56.107 に答える
5

記録として、 Python 3での項目ごとの削除による簡単な解決策( Boto3scan()を使用): (資格情報を設定する必要があります。)

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+) そのためには、削除/再作成のアプローチが安価で効率的です。

于 2016-01-21T13:33:00.917 に答える
4

テーブルを削除できない場合は、BatchWriteItemを使用する必要があります。すべてのエントリが 1 つの HashKey 内にある場合は、クエリ API を使用してレコードを取得し、一度に 25 項目ずつ削除できます。そうでない場合は、おそらくスキャンする必要があります。

AmazonDynamoDBClientまたは、テーブルに存在するハッシュ/範囲キーのセットを収集する単純なラッパー (公式 SDK から) を提供することもできます。そうすれば、テスト後に挿入したアイテムをクエリまたはスキャンする必要はありません。これは、セットが既に構築されているためです。それは次のようになります。

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
}

KeyDynamoDB SDK内のクラスでありAttributeValue、ハッシュ キーまたはハッシュ/範囲キーを表すために、コンストラクターで0 個、1 個、または 2 個のオブジェクトを受け入れます。それとメソッドが機能すると仮定するとequals、説明hashCodeした範囲内で使用できますSet。そうでない場合は、独自のKeyクラスを作成する必要があります。

これにより、テスト内で使用するための維持された Set が取得されます。テーブルに固有のものではないため、複数のテーブルを使用している場合は、コレクションの別のレイヤーを追加する必要がある場合があります。それはSet<Key>のようなものに変わりMap<TableName, Set<Key>>ます。更新getTableName()する正しいものを選択するには、プロパティを確認する必要があります。Set

テストが終了したら、テーブルの内容を取得して削除するのは簡単です。

最後に 1 つの提案: テストには、アプリケーションとは異なるテーブルを使用してください。同一のスキーマを作成しますが、テーブルに別の名前を付けます。テスト コードが本番テーブルにアクセスできないように、別の IAM ユーザーが必要になる場合もあります。それについて質問がある場合は、そのシナリオについて別の質問を開いてください。

于 2013-04-13T16:09:45.150 に答える