处理过期项目 - Amazon DynamoDB
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

处理过期项目

可以通过读取和写入操作筛选待删除的过期项目。这在过期数据不再有效且不会使用的情况下很有用。如果未将其筛选出来,它们将继续显示在读取和写入操作中,直到它们被后台进程删除。

注意

这些项目在被删除之前仍会计入存储和读取费用中。

可以在 DynamoDB Streams 中识别 TTL 删除,但只能在执行删除的区域中识别。对于删除复制到的区域,复制到全局表区域的 TTL 删除在 DynamoDB Streams 中无法识别。

从读取操作中筛选过期项目

对于诸如扫描查询之类的读取操作,筛选表达式可以筛选出待删除的过期项目。如下面的代码段所示,筛选表达式可以筛选出 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 时间不变,但 updatedAtexpireAt 时间已更新。现在,expireAt 时间设置为自上次更新时间(即 2023 年 10 月 19 日星期四下午 1:27:15)起 90 天。

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 时间不变,但 updatedAtexpireAt 时间已更新。现在,expireAt 时间设置为自上次更新时间(即 2023 年 10 月 19 日星期四下午 1:27:15)起 90 天。

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 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" } ... } ]