期限切れ項目の操作 - Amazon DynamoDB

期限切れ項目の操作

削除が保留になっている期限切れのアイテムは、読み取り操作と書き込み操作の対象から除外できます。これは、期限切れのデータが無効になり、使用すべきではなくなった場合に役に立ちます。フィルターが適用されていないと、バックグラウンドプロセスによって削除されるまで、読み取り/書き込み操作で引き続き表示されます。

注記

これらのアイテムは、削除されるまではストレージコストと読み取りコストにカウントされます。

TTL 削除は DynamoDB ストリームで確認できますが、削除が行われたリージョンでのみ確認できます。グローバルテーブルリージョンにレプリケートされた TTL 削除は、削除がレプリケートされたリージョンの DynamoDB ストリームでは確認できません。

期限切れの項目を読み取り操作から除外する

ScanQuery などの読み取り操作では、フィルター式を使用して削除待ちの期限切れアイテムを除外できます。以下のコードスニペットに示すように、フィルター式は TTL 時間が現在の時刻と同じかそれ以下の項目を除外できます。そのためには、現在の時刻を変数 (now) として取得する代入ステートメントを使用し、これをエポックタイム形式のために int に変換します。

Python
import boto3 from datetime import datetime def query_dynamodb_items(table_name, partition_key): """ :param table_name: Name of the DynamoDB table :param partition_key: :return: """ try: # Initialize a DynamoDB resource dynamodb = boto3.resource('dynamodb', region_name='us-east-1') # Specify your table table = dynamodb.Table(table_name) # Get the current time in epoch format current_time = int(datetime.now().timestamp()) # Perform the query operation with a filter expression to exclude expired items # response = table.query( # KeyConditionExpression=boto3.dynamodb.conditions.Key('partitionKey').eq(partition_key), # FilterExpression=boto3.dynamodb.conditions.Attr('expireAt').gt(current_time) # ) response = table.query( KeyConditionExpression=dynamodb.conditions.Key('partitionKey').eq(partition_key), FilterExpression=dynamodb.conditions.Attr('expireAt').gt(current_time) ) # Print the items that are not expired for item in response['Items']: print(item) except Exception as e: print(f"Error querying items: {e}") # Call the function with your values query_dynamodb_items('Music', 'your-partition-key-value')

更新操作の出力から、createdAt 時刻は変更されていないが、updatedAt 時刻と expireAt 時刻が更新されていることがわかります。expireAt 時刻は、最終更新日から 90 日後である 2023 年 10 月 19 日 (木) 午後 1 時 27 分 15 秒に設定されました。

partition_key createdAt updatedAt expireAt attribute_1 attribute_2

some_value

2023-07-17 14:11:05.322323 2023-07-19 13:27:15.213423 1697722035 new_value some_value
Javascript
import { DynamoDBClient, QueryCommand } from "@aws-sdk/client-dynamodb"; import { marshall, unmarshall } from "@aws-sdk/util-dynamodb"; async function queryDynamoDBItems(tableName, region, primaryKey) { const client = new DynamoDBClient({ region: region, endpoint: `https://dynamodb.${region}.amazonaws.com` }); const currentTime = Math.floor(Date.now() / 1000); const params = { TableName: tableName, KeyConditionExpression: "#pk = :pk", FilterExpression: "#ea > :ea", ExpressionAttributeNames: { "#pk": "primaryKey", "#ea": "expireAt" }, ExpressionAttributeValues: marshall({ ":pk": primaryKey, ":ea": currentTime }) }; try { const { Items } = await client.send(new QueryCommand(params)); Items.forEach(item => { console.log(unmarshall(item)) }); return Items; } catch (err) { console.error(`Error querying items: ${err}`); throw err; } } //enter your own values here queryDynamoDBItems('your-table-name', 'your-partition-key-value');

期限切れのアイテムに条件付きで書き込む

条件式を使用すると、期限切れのアイテムに対する書き込みを回避できます。以下のコードスニペットは、有効期限が現在の時間よりも大きいかどうかをチェックする条件付き更新です。true の場合、書き込みオペレーションは続行されます。

Python
import boto3 from datetime import datetime, timedelta from botocore.exceptions import ClientError def update_dynamodb_item(table_name, region, primary_key, sort_key, ttl_attribute): """ Updates an existing record in a DynamoDB table with a new or updated TTL attribute. :param table_name: Name of the DynamoDB table :param region: AWS Region of the table - example `us-east-1` :param primary_key: one attribute known as the partition key. :param sort_key: Also known as a range attribute. :param ttl_attribute: name of the TTL attribute in the target DynamoDB table :return: """ try: dynamodb = boto3.resource('dynamodb', region_name=region) table = dynamodb.Table(table_name) # Generate updated TTL in epoch second format updated_expiration_time = int((datetime.now() + timedelta(days=90)).timestamp()) # Define the update expression for adding/updating a new attribute update_expression = "SET newAttribute = :val1" # Define the condition expression for checking if 'ttlExpirationDate' is not expired condition_expression = "ttlExpirationDate > :val2" # Define the expression attribute values expression_attribute_values = { ':val1': ttl_attribute, ':val2': updated_expiration_time } response = table.update_item( Key={ 'primaryKey': primary_key, 'sortKey': sort_key }, UpdateExpression=update_expression, ConditionExpression=condition_expression, ExpressionAttributeValues=expression_attribute_values ) print("Item updated successfully.") return response['ResponseMetadata']['HTTPStatusCode'] # Ideally a 200 OK except ClientError as e: if e.response['Error']['Code'] == "ConditionalCheckFailedException": print("Condition check failed: Item's 'ttlExpirationDate' is expired.") else: print(f"Error updating item: {e}") except Exception as e: print(f"Error updating item: {e}") # replace with your values update_dynamodb_item('your-table-name', 'us-east-1', 'your-partition-key-value', 'your-sort-key-value', 'your-ttl-attribute-value')

更新操作の出力から、createdAt 時刻は変更されていないが、updatedAt 時刻と expireAt 時刻が更新されていることがわかります。expireAt 時刻は、最終更新日から 90 日後である 2023 年 10 月 19 日 (木) 午後 1 時 27 分 15 秒に設定されました。

partition_key createdAt updatedAt expireAt attribute_1 attribute_2

some_value

2023-07-17 14:11:05.322323 2023-07-19 13:27:15.213423 1697722035 new_value some_value
Javascript
import { DynamoDBClient, UpdateItemCommand } from "@aws-sdk/client-dynamodb"; import { marshall, unmarshall } from "@aws-sdk/util-dynamodb"; // Example function to update an item in a DynamoDB table. // The function should take the table name, region, partition key, sort key, and new attribute as arguments. // The function should use the DynamoDB client to update the item. // The function should return the updated item. // The function should handle errors and exceptions. const updateDynamoDBItem = async (tableName, region, partitionKey, sortKey, newAttribute) => { const client = new DynamoDBClient({ region: region, endpoint: `https://dynamodb.${region}.amazonaws.com` }); const currentTime = Math.floor(Date.now() / 1000); const params = { TableName: tableName, Key: marshall({ artist: partitionKey, album: sortKey }), UpdateExpression: "SET newAttribute = :newAttribute", ConditionExpression: "expireAt > :expiration", ExpressionAttributeValues: marshall({ ':newAttribute': newAttribute, ':expiration': currentTime }), ReturnValues: "ALL_NEW" }; try { const response = await client.send(new UpdateItemCommand(params)); const responseData = unmarshall(response.Attributes); console.log("Item updated successfully: ", responseData); return responseData; } catch (error) { if (error.name === "ConditionalCheckFailedException") { console.log("Condition check failed: Item's 'expireAt' is expired."); } else { console.error("Error updating item: ", error); } throw error; } }; // Enter your values here updateDynamoDBItem('your-table-name', "us-east-1",'your-partition-key-value', 'your-sort-key-value', 'your-new-attribute-value');

DynamoDB ストリーム内の削除済みアイテムの特定

ストリームレコードにはユーザー ID フィールド Records[<index>].userIdentity が含まれます。TTL プロセスによって削除された項目には、次のフィールドが含まれています。

Records[<index>].userIdentity.type "Service" Records[<index>].userIdentity.principalId "dynamodb.amazonaws.com"

次の JSON は 1 つのストリームレコードの関連する部分を示しています。

"Records": [ { ... "userIdentity": { "type": "Service", "principalId": "dynamodb.amazonaws.com" } ... } ]