使用過期的物品 - Amazon DynamoDB

本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。

使用過期的物品

可以從讀取和寫入作業中篩選擱置刪除的過期項目。這在過期的數據不再有效且不應該被使用的情況下很有用。如果未篩選它們,它們將繼續顯示在讀取和寫入作業中,直到背景處理程序將它們刪除為止。

注意

這些項目仍會計入儲存和讀取成本,直到它們被刪除為止。

TTL 刪除可以在 DynamoDB Streams 中識別,但只能在發生刪除的區域中識別。複寫至全域資料表區域的 TTL 刪除作業在刪除複寫目標區域的 DynamoDB 串流中無法識別。

從讀取作業中篩選過期的項目

對於掃描查詢等讀取作業,篩選器運算式可以篩選出擱置刪除的過期項目。如下列程式碼片段所示,篩選器運算式可以篩選出 TTL 時間等於或小於目前時間的項目。這是通過一個賦值語句來完成的,該語句將當前時間作為一個變量(now),該變量被轉換int為 epoch 時間格式。

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時間不變,但updatedAtexpireAt時間已更新。現在expireAt時間設定為上次更新時間起 90 天,即 2023 年 10 月 19 日(星期四)下午 1:27:15。

partition_key createdAt updatedAt 到期時間 屬性 _1 屬性 _2

某些值

2023-07-17 14:11:05.322 323 2023-07-19 13:27:15.213 423 1697722035 new_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時間不變,但updatedAtexpireAt時間已更新。現在expireAt時間設定為上次更新時間起 90 天,即 2023 年 10 月 19 日(星期四)下午 1:27:15。

partition_key createdAt updatedAt 到期時間 屬性 _1 屬性 _2

某些值

2023-07-17 14:11:05.322 323 2023-07-19 13:27:15.213 423 1697722035 new_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 Streams 中識別已刪除的項目

串流紀錄包含使用者身分欄位 Records[<index>].userIdentity。由 TTL 程序刪除的項目具有下列欄位:

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

下列 JSON 會顯示單一串流記錄的相關部分:

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