Utilisation d'articles expirés et durée de vie (TTL) - Amazon DynamoDB

Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.

Utilisation d'articles expirés et durée de vie (TTL)

Les éléments expirés en attente de suppression peuvent être exclus des opérations de lecture et d'écriture. Cela est utile dans les scénarios où les données expirées ne sont plus valides et ne doivent pas être utilisées. S'ils ne sont pas filtrés, ils continueront à s'afficher dans les opérations de lecture et d'écriture jusqu'à ce qu'ils soient supprimés par le processus en arrière-plan.

Note

Ces éléments sont toujours pris en compte dans les coûts de stockage et de lecture jusqu'à ce qu'ils soient supprimés.

TTLles suppressions peuvent être identifiées dans DynamoDB Streams, mais uniquement dans la région où la suppression a eu lieu. TTLles suppressions répliquées dans les régions de table globales ne sont pas identifiables dans les flux DynamoDB des régions vers lesquelles la suppression est répliquée.

Filtrer les éléments expirés des opérations de lecture

Pour les opérations de lecture telles que Scan et Query, une expression de filtre peut filtrer les éléments expirés en attente de suppression. Comme indiqué dans l'extrait de code suivant, l'expression du filtre peut filtrer les éléments dont l'TTLheure est égale ou inférieure à l'heure actuelle. Par exemple, le SDK code Python inclut une instruction d'assignation qui obtient l'heure actuelle sous forme de variable (now) et la convertit au format int for epoch time.

Les exemples de code suivants montrent comment rechercher des TTL éléments.

Java
SDKpour Java 2.x

Expression filtrée par requête pour rassembler TTL des éléments dans une table DynamoDB.

import software.amazon.awssdk.regions.Region; import software.amazon.awssdk.services.dynamodb.DynamoDbClient; import software.amazon.awssdk.services.dynamodb.model.AttributeValue; import software.amazon.awssdk.services.dynamodb.model.DynamoDbException; import software.amazon.awssdk.services.dynamodb.model.QueryRequest; import software.amazon.awssdk.services.dynamodb.model.QueryResponse; import software.amazon.awssdk.services.dynamodb.model.ResourceNotFoundException; import software.amazon.awssdk.utils.ImmutableMap; import java.util.Map; import java.util.Optional; // Get current time in epoch second format (comparing against expiry attribute) final long currentTime = System.currentTimeMillis() / 1000; // A string that contains conditions that DynamoDB applies after the Query operation, but before the data is returned to you. final String keyConditionExpression = "#pk = :pk"; // The condition that specifies the key values for items to be retrieved by the Query action. final String filterExpression = "#ea > :ea"; final Map<String, String> expressionAttributeNames = ImmutableMap.of( "#pk", "primaryKey", "#ea", "expireAt"); final Map<String, AttributeValue> expressionAttributeValues = ImmutableMap.of( ":pk", AttributeValue.builder().s(primaryKey).build(), ":ea", AttributeValue.builder().s(String.valueOf(currentTime)).build() ); final QueryRequest request = QueryRequest.builder() .tableName(tableName) .keyConditionExpression(keyConditionExpression) .filterExpression(filterExpression) .expressionAttributeNames(expressionAttributeNames) .expressionAttributeValues(expressionAttributeValues) .build(); try (DynamoDbClient ddb = DynamoDbClient.builder() .region(region) .build()) { final QueryResponse response = ddb.query(request); System.out.println(tableName + " Query operation with TTL successful. Request id is " + response.responseMetadata().requestId()); // Print the items that are not expired for (Map<String, AttributeValue> item : response.items()) { System.out.println(item.toString()); } } catch (ResourceNotFoundException e) { System.err.format("Error: The Amazon DynamoDB table \"%s\" can't be found.\n", tableName); System.exit(1); } catch (DynamoDbException e) { System.err.println(e.getMessage()); System.exit(1); } System.exit(0);
  • Pour API plus de détails, voir Requête en AWS SDK for Java 2.x APIréférence.

JavaScript
SDKpour JavaScript (v3)
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');
  • Pour API plus de détails, voir Requête en AWS SDK for JavaScript APIréférence.

Python
SDKpour Python (Boto3)
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')

Écrire de manière conditionnelle aux articles expirés

Une expression de condition peut être utilisée pour éviter les écritures sur des éléments expirés. L'extrait de code ci-dessous est une mise à jour conditionnelle qui vérifie si le délai d'expiration est supérieur à l'heure actuelle. Si c'est vrai, l'opération d'écriture se poursuivra.

Les exemples de code suivants montrent comment mettre à jour de manière conditionnelle celui d'un élément. TTL

Java
SDKpour Java 2.x
package com.amazon.samplelib.ttl; import software.amazon.awssdk.regions.Region; import software.amazon.awssdk.services.dynamodb.DynamoDbClient; import software.amazon.awssdk.services.dynamodb.model.AttributeValue; import software.amazon.awssdk.services.dynamodb.model.DynamoDbException; import software.amazon.awssdk.services.dynamodb.model.ResourceNotFoundException; import software.amazon.awssdk.services.dynamodb.model.UpdateItemRequest; import software.amazon.awssdk.services.dynamodb.model.UpdateItemResponse; import software.amazon.awssdk.utils.ImmutableMap; import java.util.Map; import java.util.Optional; public class UpdateTTLConditional { public static void main(String[] args) { final String usage = """ Usage: <tableName> <primaryKey> <sortKey> <newTtlAttribute> <region> Where: tableName - The Amazon DynamoDB table being queried. primaryKey - The name of the primary key. Also known as the hash or partition key. sortKey - The name of the sort key. Also known as the range attribute. newTtlAttribute - New attribute name (as part of the update command) region (optional) - The AWS region that the Amazon DynamoDB table is located in. (Default: us-east-1) """; // Optional "region" parameter - if args list length is NOT 3 or 4, short-circuit exit. if (!(args.length == 4 || args.length == 5)) { System.out.println(usage); System.exit(1); } final String tableName = args[0]; final String primaryKey = args[1]; final String sortKey = args[2]; final String newTtlAttribute = args[3]; Region region = Optional.ofNullable(args[4]).isEmpty() ? Region.US_EAST_1 : Region.of(args[4]); // Get current time in epoch second format final long currentTime = System.currentTimeMillis() / 1000; // Calculate expiration time 90 days from now in epoch second format final long expireDate = currentTime + (90 * 24 * 60 * 60); // An expression that defines one or more attributes to be updated, the action to be performed on them, and new values for them. final String updateExpression = "SET newTtlAttribute = :val1"; // A condition that must be satisfied in order for a conditional update to succeed. final String conditionExpression = "expireAt > :val2"; final ImmutableMap<String, AttributeValue> keyMap = ImmutableMap.of("primaryKey", AttributeValue.fromS(primaryKey), "sortKey", AttributeValue.fromS(sortKey)); final Map<String, AttributeValue> expressionAttributeValues = ImmutableMap.of( ":val1", AttributeValue.builder().s(newTtlAttribute).build(), ":val2", AttributeValue.builder().s(String.valueOf(expireDate)).build() ); final UpdateItemRequest request = UpdateItemRequest.builder() .tableName(tableName) .key(keyMap) .updateExpression(updateExpression) .conditionExpression(conditionExpression) .expressionAttributeValues(expressionAttributeValues) .build(); try (DynamoDbClient ddb = DynamoDbClient.builder() .region(region) .build()) { final UpdateItemResponse response = ddb.updateItem(request); System.out.println(tableName + " UpdateItem operation with conditional TTL successful. Request id is " + response.responseMetadata().requestId()); } catch (ResourceNotFoundException e) { System.err.format("Error: The Amazon DynamoDB table \"%s\" can't be found.\n", tableName); System.exit(1); } catch (DynamoDbException e) { System.err.println(e.getMessage()); System.exit(1); } System.exit(0); } }
  • Pour API plus de détails, voir UpdateItemla section AWS SDK for Java 2.x APIRéférence.

JavaScript
SDKpour JavaScript (v3)

Effectuez une mise à jour TTL sur un élément DynamoDB existant dans une table, avec une condition.

import { DynamoDBClient, UpdateItemCommand } from "@aws-sdk/client-dynamodb"; import { marshall, unmarshall } from "@aws-sdk/util-dynamodb"; 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');
  • Pour API plus de détails, voir UpdateItemla section AWS SDK for JavaScript APIRéférence.

Python
SDKpour Python (Boto3)
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 'expireAt' is not expired condition_expression = "expireAt > :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 'expireAt' 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')
  • Pour API plus de détails, reportez-vous UpdateItemà la section AWS SDKpour Python (Boto3) Reference. API

Identification des éléments supprimés dans DynamoDB Streams

L'enregistrement de flux contient un champ d'identité utilisateur Records[<index>].userIdentity. Les éléments supprimés par le TTL processus comportent les champs suivants :

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

Ce qui suit JSON montre la partie pertinente d'un enregistrement de flux unique :

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