

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 de la durée de vie (TTL) dans DynamoDB
<a name="TTL"></a>

La durée de vie (TTL) de DynamoDB est une méthode économique pour supprimer les éléments qui ne sont plus pertinents. Elle vous permet de définir un horodatage d’expiration par élément pour indiquer quand cet élément n’est plus nécessaire. DynamoDB supprime automatiquement les éléments ayant expiré quelques jours après leur date d’expiration, sans consommer de débit d’écriture. 

Pour utiliser la TTL, activez-la d’abord sur une table, puis définissez un attribut spécifique pour stocker l’horodatage d’expiration de la TTL. L'horodatage doit être stocké sous la forme d'un type de données [numérique](HowItWorks.NamingRulesDataTypes.md#HowItWorks.DataTypes) au [format Epoch Time Unix](https://en.wikipedia.org/wiki/Unix_time) avec une granularité en secondes. Les éléments dont l'attribut TTL n'est pas de type numérique sont ignorés par le processus TTL. Chaque fois qu’un élément est créé ou mis à jour, vous pouvez calculer le délai d’expiration et l’enregistrer dans l’attribut TTL.

Les éléments dont les attributs TTL sont valides et ayant expiré peuvent être supprimés par le système à tout moment, généralement quelques jours après leur expiration. Vous pouvez à tout moment mettre à jour les éléments ayant expiré qui sont en attente de suppression, notamment en modifiant ou en supprimant leurs attributs TTL. Lors de la mise à jour d’un élément ayant expiré, nous vous recommandons d’utiliser une expression conditionnelle pour vous assurer que l’élément n’a pas été supprimé ultérieurement. Utilisez des expressions de filtre pour supprimer les éléments ayant expiré des résultats [Scan](Scan.md#Scan.FilterExpression) et [Query](Query.FilterExpression.md).

Les éléments supprimés fonctionnent de la même manière que ceux supprimés par le biais d’opérations de suppression classiques. Une fois supprimés, les éléments sont placés dans DynamoDB Streams sous forme de suppression de service au lieu d’être supprimés par l’utilisateur, et sont supprimés des index secondaires locaux et globaux comme avec les autres opérations de suppression. 

Si vous utilisez des [tables globales version 2019.11.21 (actuelle)](GlobalTables.md) et que vous utilisez également la fonctionnalité TTL, DynamoDB réplique les suppressions par TTL sur toutes les tables de réplica. La suppression par TTL initiale ne consomme pas d’unités de capacité d’écriture (WCU) dans la région dans laquelle l’expiration de la TTL a lieu. Toutefois, la suppression par TTL répliquée dans les tables de réplica consomme une unité de capacité d’écriture répliquée lorsque vous utilisez la capacité provisionnée ou une unité d’écriture répliquée lorsque vous utilisez le mode de capacité à la demande, dans chacune des régions de réplica, et des frais s’appliquent.

Pour plus d’informations sur TTL, veuillez consulter les rubriques suivantes :

**Topics**
+ [Activation de la durée de vie (TTL) dans DynamoDB](time-to-live-ttl-how-to.md)
+ [Calcul de la durée de vie (TTL) dans DynamoDB](time-to-live-ttl-before-you-start.md)
+ [Utilisation des éléments ayant expiré et de la durée de vie (TTL)](ttl-expired-items.md)

# Activation de la durée de vie (TTL) dans DynamoDB
<a name="time-to-live-ttl-how-to"></a>

**Note**  
Pour faciliter le débogage et la vérification de la fonctionnalité TTL, les valeurs fournies pour la TTL de l’élément sont journalisées en texte brut dans les journaux de diagnostic DynamoDB.

Vous pouvez activer le TTL dans la console Amazon DynamoDB, le () AWS Command Line Interface , ou en utilisant AWS CLI le [Amazon DynamoDB API Reference avec n'importe lequel des supposés](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/). AWS SDKs L’activation de la durée de vie (TTL) sur toutes les partitions prend environ une heure.

## Activer DynamoDB TTL à l'aide de la console AWS
<a name="time-to-live-ttl-how-to-enable-console"></a>

1. Connectez-vous à la console DynamoDB AWS Management Console et ouvrez-la à l'adresse. [https://console.aws.amazon.com/dynamodb/](https://console.aws.amazon.com/dynamodb/)

1. Choisissez **Tables**, puis choisissez la table à modifier.

1. Dans l’onglet **Paramètres supplémentaires**, dans la section **Durée de vie (TTL)**, choisissez **Activer**.

1. Lorsque vous activez TTL sur une table, vous devez identifier un nom d’attribut spécifique que le service DynamoDB recherchera pour déterminer si un élément peut faire l’objet d’une expiration. Le nom de l’attribut TTL, illustré ci-dessous, distingue les majuscules et minuscules et doit correspondre à l’attribut défini dans vos opérations de lecture et d’écriture. En cas de non-concordance, les éléments ayant expiré ne seront pas supprimés. Pour renommer l’attribut TTL, vous devez le désactiver, puis le réactiver avec le nouveau nom. La TTL continue à traiter les suppressions pendant environ 30 minutes après sa désactivation. Elle doit être reconfigurée sur les tables restaurées.  
![\[Nom d’attribut TTL (distinguant majuscules et minuscules) utilisé par DynamoDB pour déterminer si un élément doit expirer.\]](http://docs.aws.amazon.com/fr_fr/amazondynamodb/latest/developerguide/images/EnableTTL-Settings.png)

1. (Facultatif) Vous pouvez effectuer un test en simulant la date et l’heure de l’expiration et en faisant correspondre quelques éléments. Cela vous fournit un exemple de liste d’éléments et confirme qu’il existe des éléments contenant le nom d’attribut TTL fourni avec la date d’expiration.

Une fois que la TTL est activée, l’attribut TTL est marqué **TTL** lorsque vous affichez les éléments dans la console DynamoDB. Vous pouvez afficher la date et l’heure d’expiration d’un élément en faisant passer votre souris au-dessus de l’attribut. 

## Activation de la TTL DynamoDB à l’aide de l’API
<a name="time-to-live-ttl-how-to-enable-api"></a>

------
#### [ Python ]

Vous pouvez activer le TTL avec du code à l'aide de l'[UpdateTimeToLive](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/dynamodb/client/update_time_to_live.html)opération.

```
import boto3


def enable_ttl(table_name, ttl_attribute_name):
    """
    Enables TTL on DynamoDB table for a given attribute name
        on success, returns a status code of 200
        on error, throws an exception

    :param table_name: Name of the DynamoDB table
    :param ttl_attribute_name: The name of the TTL attribute being provided to the table.
    """
    try:
        dynamodb = boto3.client('dynamodb')

        # Enable TTL on an existing DynamoDB table
        response = dynamodb.update_time_to_live(
            TableName=table_name,
            TimeToLiveSpecification={
                'Enabled': True,
                'AttributeName': ttl_attribute_name
            }
        )

        # In the returned response, check for a successful status code.
        if response['ResponseMetadata']['HTTPStatusCode'] == 200:
            print("TTL has been enabled successfully.")
        else:
            print(f"Failed to enable TTL, status code {response['ResponseMetadata']['HTTPStatusCode']}")
    except Exception as ex:
        print("Couldn't enable TTL in table %s. Here's why: %s" % (table_name, ex))
        raise


# your values
enable_ttl('your-table-name', 'expirationDate')
```

Vous pouvez confirmer que le TTL est activé à l'aide de l'[DescribeTimeToLive](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/dynamodb/client/describe_time_to_live.html)opération, qui décrit l'état du TTL sur une table. L’état `TimeToLive` est `ENABLED` ou `DISABLED`.

```
# create a DynamoDB client
dynamodb = boto3.client('dynamodb')

# set the table name
table_name = 'YourTable'

# describe TTL
response = dynamodb.describe_time_to_live(TableName=table_name)
```

------
#### [ JavaScript ]

Vous pouvez activer le TTL avec du code à l'aide de l'[UpdateTimeToLiveCommand](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/Package/-aws-sdk-client-dynamodb/Class/UpdateTimeToLiveCommand/)opération.

```
import { DynamoDBClient, UpdateTimeToLiveCommand } from "@aws-sdk/client-dynamodb";

const enableTTL = async (tableName, ttlAttribute) => {

    const client = new DynamoDBClient({});

    const params = {
        TableName: tableName,
        TimeToLiveSpecification: {
            Enabled: true,
            AttributeName: ttlAttribute
        }
    };

    try {
        const response = await client.send(new UpdateTimeToLiveCommand(params));
        if (response.$metadata.httpStatusCode === 200) {
            console.log(`TTL enabled successfully for table ${tableName}, using attribute name ${ttlAttribute}.`);
        } else {
            console.log(`Failed to enable TTL for table ${tableName}, response object: ${response}`);
        }
        return response;
    } catch (e) {
        console.error(`Error enabling TTL: ${e}`);
        throw e;
    }
};

// call with your own values
enableTTL('ExampleTable', 'exampleTtlAttribute');
```

------

## Activez Time to Live à l'aide du AWS CLI
<a name="time-to-live-ttl-how-to-enable-cli-sdk"></a>

1. Active TTL sur la table `TTLExample`.

   ```
   aws dynamodb update-time-to-live --table-name TTLExample --time-to-live-specification "Enabled=true, AttributeName=ttl"
   ```

1. Décrit TTL sur la table `TTLExample`.

   ```
   aws dynamodb describe-time-to-live --table-name TTLExample
   {
       "TimeToLiveDescription": {
           "AttributeName": "ttl",
           "TimeToLiveStatus": "ENABLED"
       }
   }
   ```

1. Ajoutez un élément à la table `TTLExample` avec l’attribut de TTL défini à l’aide du shell BASH et de l’ AWS CLI. 

   ```
   EXP=`date -d '+5 days' +%s`
   aws dynamodb put-item --table-name "TTLExample" --item '{"id": {"N": "1"}, "ttl": {"N": "'$EXP'"}}'
   ```

Cet exemple démarre par la date actuelle à laquelle cinq jours sont ajoutés pour créer une date d’expiration. Il a ensuite converti l’heure d’expiration en heure au format epoch pour ajouter en dernier lieu un élément à la table « `TTLExample` ». 

**Note**  
 Pour définir des valeurs d’expiration pour TTL, l’une des méthodes à votre disposition consiste à calculer le nombre de secondes à ajouter à l’heure d’expiration. Par exemple, 5 jours équivalent à 432 000 secondes. Toutefois, il est souvent préférable de commencer par une date et de définir le reste en fonction de celle-ci.

Il est relativement simple d’obtenir l’heure actuelle au format epoch, comme dans l’exemple suivant.
+ Terminal Linux : `date +%s`
+ Python: `import time; int(time.time())`
+ Java: `System.currentTimeMillis() / 1000L`
+ JavaScript: `Math.floor(Date.now() / 1000)`

## Activez DynamoDB TTL à l'aide de CloudFormation
<a name="time-to-live-ttl-how-to-enable-cf"></a>

```
AWSTemplateFormatVersion: "2010-09-09"
Resources:
  TTLExampleTable:
    Type: AWS::DynamoDB::Table
    Description: "A DynamoDB table with TTL Specification enabled"
    Properties:
      AttributeDefinitions:
        - AttributeName: "Album"
          AttributeType: "S"
        - AttributeName: "Artist"
          AttributeType: "S"
      KeySchema:
        - AttributeName: "Album"
          KeyType: "HASH"
        - AttributeName: "Artist"
          KeyType: "RANGE"
      ProvisionedThroughput:
        ReadCapacityUnits: "5"
        WriteCapacityUnits: "5"
      TimeToLiveSpecification:
        AttributeName: "TTLExampleAttribute"
        Enabled: true
```

Vous trouverez des informations supplémentaires sur l'utilisation du TTL dans vos CloudFormation modèles [ici](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-dynamodb-table-timetolivespecification.html).

# Calcul de la durée de vie (TTL) dans DynamoDB
<a name="time-to-live-ttl-before-you-start"></a>

Une méthode courante pour implémenter la durée de vie, ou TTL, consiste à définir un délai d’expiration pour les éléments en fonction de leur date de création ou de dernière mise à jour. Cela peut être fait en ajoutant l’heure aux horodatages `createdAt` et `updatedAt`. Par exemple, la TTL des éléments qui viennent d’être créés peut être défini sur `createdAt` \$1 90 jours. Lorsque l’élément est mis à jour, la TTL peut être recalculée sur `updatedAt` \$1 90 jours.

Le délai d’expiration calculé doit être au format epoch, en secondes. Pour que l’expiration et la suppression soient prises en compte, la TTL ne doit pas dater de plus de cinq ans. Si vous utilisez un autre format, les processus TTL ignorent l’élément. Si vous définissez le délai d'expiration à un moment futur où vous souhaitez que l'article expire, l'article expirera après cette date. Supposons, par exemple, que vous définissiez l'heure d'expiration sur 1724241326 (c'est-à-dire le lundi 21 août 2024 11:55:26 (UTC)). L'article expire après le délai spécifié. Il n'y a pas de durée TTL minimale. Vous pouvez définir l'heure d'expiration à n'importe quelle date future, par exemple 5 minutes à compter de l'heure actuelle. Toutefois, DynamoDB supprime généralement les éléments expirés dans les 48 heures suivant leur date d'expiration, et non immédiatement après leur expiration.

**Topics**
+ [Création d’un élément et définition de la durée de vie (TTL)](#time-to-live-ttl-before-you-start-create)
+ [Mise à jour d’un élément et actualisation de la durée de vie (TTL)](#time-to-live-ttl-before-you-start-update)

## Création d’un élément et définition de la durée de vie (TTL)
<a name="time-to-live-ttl-before-you-start-create"></a>

L’exemple suivant montre comment calculer le délai d’expiration lors de la création d’un élément, en utilisant `expireAt` comme nom d’attribut TTL. Une instruction d’affectation obtient l’heure actuelle sous forme de variable. Dans l’exemple, le délai d’expiration est calculé comme étant de 90 jours à compter de l’heure actuelle. L’heure est ensuite convertie au format epoch et enregistrée sous forme de type de données « entier » dans l’attribut TTL.

Les exemples de code suivants montrent comment créer un élément avec une TTL.

------
#### [ Java ]

**SDK pour Java 2.x**  

```
package com.amazon.samplelib.ttl;

import com.amazon.samplelib.CodeSampleUtils;
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.PutItemRequest;
import software.amazon.awssdk.services.dynamodb.model.PutItemResponse;
import software.amazon.awssdk.services.dynamodb.model.ResourceNotFoundException;

import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

/**
 * Creates an item in a DynamoDB table with TTL attributes.
 * This class demonstrates how to add TTL expiration timestamps to DynamoDB items.
 */
public class CreateTTL {

    private static final String USAGE =
        """
            Usage:
                <tableName> <primaryKey> <sortKey> <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.
                region (optional) - The AWS region that the Amazon DynamoDB table is located in. (Default: us-east-1)
            """;
    private static final int DAYS_TO_EXPIRE = 90;
    private static final int SECONDS_PER_DAY = 24 * 60 * 60;
    private static final String PRIMARY_KEY_ATTR = "primaryKey";
    private static final String SORT_KEY_ATTR = "sortKey";
    private static final String CREATION_DATE_ATTR = "creationDate";
    private static final String EXPIRE_AT_ATTR = "expireAt";
    private static final String SUCCESS_MESSAGE = "%s PutItem operation with TTL successful.";
    private static final String TABLE_NOT_FOUND_ERROR = "Error: The Amazon DynamoDB table \"%s\" can't be found.";

    private final DynamoDbClient dynamoDbClient;

    /**
     * Constructs a CreateTTL instance with the specified DynamoDB client.
     *
     * @param dynamoDbClient The DynamoDB client to use
     */
    public CreateTTL(final DynamoDbClient dynamoDbClient) {
        this.dynamoDbClient = dynamoDbClient;
    }

    /**
     * Constructs a CreateTTL with a default DynamoDB client.
     */
    public CreateTTL() {
        this.dynamoDbClient = null;
    }

    /**
     * Main method to demonstrate creating an item with TTL.
     *
     * @param args Command line arguments
     */
    public static void main(final String[] args) {
        try {
            int result = new CreateTTL().processArgs(args);
            System.exit(result);
        } catch (Exception e) {
            System.err.println(e.getMessage());
            System.exit(1);
        }
    }

    /**
     * Process command line arguments and create an item with TTL.
     *
     * @param args Command line arguments
     * @return 0 if successful, non-zero otherwise
     * @throws ResourceNotFoundException If the table doesn't exist
     * @throws DynamoDbException If an error occurs during the operation
     * @throws IllegalArgumentException If arguments are invalid
     */
    public int processArgs(final String[] args) {
        // Argument validation (remove or replace this line when reusing this code)
        CodeSampleUtils.validateArgs(args, new int[] {3, 4}, USAGE);

        final String tableName = args[0];
        final String primaryKey = args[1];
        final String sortKey = args[2];
        final Region region = Optional.ofNullable(args.length > 3 ? args[3] : null)
            .map(Region::of)
            .orElse(Region.US_EAST_1);

        try (DynamoDbClient ddb = dynamoDbClient != null
            ? dynamoDbClient
            : DynamoDbClient.builder().region(region).build()) {
            final CreateTTL createTTL = new CreateTTL(ddb);
            createTTL.createItemWithTTL(tableName, primaryKey, sortKey);
            return 0;
        } catch (Exception e) {
            throw e;
        }
    }

    /**
     * Creates an item in the specified table with TTL attributes.
     *
     * @param tableName The name of the table
     * @param primaryKeyValue The value for the primary key
     * @param sortKeyValue The value for the sort key
     * @return The response from the PutItem operation
     * @throws ResourceNotFoundException If the table doesn't exist
     * @throws DynamoDbException If an error occurs during the operation
     */
    public PutItemResponse createItemWithTTL(
        final String tableName, final String primaryKeyValue, final String sortKeyValue) {
        // Get current time in epoch second format
        final long createDate = System.currentTimeMillis() / 1000;

        // Calculate expiration time 90 days from now in epoch second format
        final long expireDate = createDate + (DAYS_TO_EXPIRE * SECONDS_PER_DAY);

        final Map<String, AttributeValue> itemMap = new HashMap<>();
        itemMap.put(
            PRIMARY_KEY_ATTR, AttributeValue.builder().s(primaryKeyValue).build());
        itemMap.put(SORT_KEY_ATTR, AttributeValue.builder().s(sortKeyValue).build());
        itemMap.put(
            CREATION_DATE_ATTR,
            AttributeValue.builder().n(String.valueOf(createDate)).build());
        itemMap.put(
            EXPIRE_AT_ATTR,
            AttributeValue.builder().n(String.valueOf(expireDate)).build());

        final PutItemRequest request =
            PutItemRequest.builder().tableName(tableName).item(itemMap).build();

        try {
            final PutItemResponse response = dynamoDbClient.putItem(request);
            System.out.println(String.format(SUCCESS_MESSAGE, tableName));
            return response;
        } catch (ResourceNotFoundException e) {
            System.err.format(TABLE_NOT_FOUND_ERROR, tableName);
            throw e;
        } catch (DynamoDbException e) {
            System.err.println(e.getMessage());
            throw e;
        }
    }
}
```
+  Pour plus de détails sur l'API, reportez-vous [PutItem](https://docs.aws.amazon.com/goto/SdkForJavaV2/dynamodb-2012-08-10/PutItem)à la section *Référence des AWS SDK for Java 2.x API*. 

------
#### [ JavaScript ]

**SDK pour JavaScript (v3)**  

```
import { DynamoDBClient, PutItemCommand } from "@aws-sdk/client-dynamodb";

export function createDynamoDBItem(table_name, region, partition_key, sort_key) {
    const client = new DynamoDBClient({
        region: region,
        endpoint: `https://dynamodb.${region}.amazonaws.com`
    });

    // Get the current time in epoch second format
    const current_time = Math.floor(new Date().getTime() / 1000);

    // Calculate the expireAt time (90 days from now) in epoch second format
    const expire_at = Math.floor((new Date().getTime() + 90 * 24 * 60 * 60 * 1000) / 1000);

    // Create DynamoDB item
    const item = {
        'partitionKey': {'S': partition_key},
        'sortKey': {'S': sort_key},
        'createdAt': {'N': current_time.toString()},
        'expireAt': {'N': expire_at.toString()}
    };

    const putItemCommand = new PutItemCommand({
        TableName: table_name,
        Item: item,
        ProvisionedThroughput: {
            ReadCapacityUnits: 1,
            WriteCapacityUnits: 1,
        },
    });

    client.send(putItemCommand, function(err, data) {
        if (err) {
            console.log("Exception encountered when creating item %s, here's what happened: ", data, err);
            throw err;
        } else {
            console.log("Item created successfully: %s.", data);
            return data;
        }
    });
}

// Example usage (commented out for testing)
// createDynamoDBItem('your-table-name', 'us-east-1', 'your-partition-key-value', 'your-sort-key-value');
```
+  Pour plus de détails sur l'API, reportez-vous [PutItem](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/client/dynamodb/command/PutItemCommand)à la section *Référence des AWS SDK pour JavaScript API*. 

------
#### [ Python ]

**Kit SDK for Python (Boto3)**  

```
from datetime import datetime, timedelta

import boto3


def create_dynamodb_item(table_name, region, primary_key, sort_key):
    """
    Creates a DynamoDB item with an attached expiry attribute.

    :param table_name: Table name for the boto3 resource to target when creating an item
    :param region: string representing the AWS region. Example: `us-east-1`
    :param primary_key: one attribute known as the partition key.
    :param sort_key: Also known as a range attribute.
    :return: Void (nothing)
    """
    try:
        dynamodb = boto3.resource("dynamodb", region_name=region)
        table = dynamodb.Table(table_name)

        # Get the current time in epoch second format
        current_time = int(datetime.now().timestamp())

        # Calculate the expiration time (90 days from now) in epoch second format
        expiration_time = int((datetime.now() + timedelta(days=90)).timestamp())

        item = {
            "primaryKey": primary_key,
            "sortKey": sort_key,
            "creationDate": current_time,
            "expireAt": expiration_time,
        }
        response = table.put_item(Item=item)

        print("Item created successfully.")
        return response
    except Exception as e:
        print(f"Error creating item: {e}")
        raise e


# Use your own values
create_dynamodb_item(
    "your-table-name", "us-west-2", "your-partition-key-value", "your-sort-key-value"
)
```
+  Pour plus de détails sur l'API, consultez [PutItem](https://docs.aws.amazon.com/goto/boto3/dynamodb-2012-08-10/PutItem)le *AWS manuel de référence de l'API SDK for Python (Boto3*). 

------

## Mise à jour d’un élément et actualisation de la durée de vie (TTL)
<a name="time-to-live-ttl-before-you-start-update"></a>

Cet exemple est la suite de la [section précédente](#time-to-live-ttl-before-you-start-create). Le délai d’expiration peut être recalculé si l’élément est mis à jour. L’exemple suivant recalcule l’horodatage `expireAt` pour qu’il corresponde à 90 jours à partir de l’heure actuelle.

Les exemples de code suivants montrent comment mettre à jour la TTL d’un élément.

------
#### [ Java ]

**SDK pour Java 2.x**  
Mise à jour de la TTL sur un élément DynamoDB existant dans une table.  

```
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 java.util.HashMap;
import java.util.Map;
import java.util.Optional;

    public UpdateItemResponse updateItemWithTTL(
        final String tableName, final String primaryKeyValue, final String sortKeyValue) {
        // 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 + (DAYS_TO_EXPIRE * SECONDS_PER_DAY);

        // Create the key map for the item to update
        final Map<String, AttributeValue> keyMap = new HashMap<>();
        keyMap.put(PRIMARY_KEY_ATTR, AttributeValue.builder().s(primaryKeyValue).build());
        keyMap.put(SORT_KEY_ATTR, AttributeValue.builder().s(sortKeyValue).build());

        // Create the expression attribute values
        final Map<String, AttributeValue> expressionAttributeValues = new HashMap<>();
        expressionAttributeValues.put(
            ":c", AttributeValue.builder().n(String.valueOf(currentTime)).build());
        expressionAttributeValues.put(
            ":e", AttributeValue.builder().n(String.valueOf(expireDate)).build());

        final UpdateItemRequest request = UpdateItemRequest.builder()
            .tableName(tableName)
            .key(keyMap)
            .updateExpression(UPDATE_EXPRESSION)
            .expressionAttributeValues(expressionAttributeValues)
            .build();

        try {
            final UpdateItemResponse response = dynamoDbClient.updateItem(request);
            System.out.println(String.format(SUCCESS_MESSAGE, tableName));
            return response;
        } catch (ResourceNotFoundException e) {
            System.err.format(TABLE_NOT_FOUND_ERROR, tableName);
            throw e;
        } catch (DynamoDbException e) {
            System.err.println(e.getMessage());
            throw e;
        }
    }
```
+  Pour plus de détails sur l'API, reportez-vous [UpdateItem](https://docs.aws.amazon.com/goto/SdkForJavaV2/dynamodb-2012-08-10/UpdateItem)à la section *Référence des AWS SDK for Java 2.x API*. 

------
#### [ JavaScript ]

**SDK pour JavaScript (v3)**  

```
import { DynamoDBClient, UpdateItemCommand } from "@aws-sdk/client-dynamodb";
import { marshall, unmarshall } from "@aws-sdk/util-dynamodb";

export const updateItem = async (tableName, partitionKey, sortKey, region = 'us-east-1') => {
    const client = new DynamoDBClient({
        region: region,
        endpoint: `https://dynamodb.${region}.amazonaws.com`
    });

    const currentTime = Math.floor(Date.now() / 1000);
    const expireAt = Math.floor((Date.now() + 90 * 24 * 60 * 60 * 1000) / 1000);

    const params = {
        TableName: tableName,
        Key: marshall({
            partitionKey: partitionKey,
            sortKey: sortKey
        }),
        UpdateExpression: "SET updatedAt = :c, expireAt = :e",
        ExpressionAttributeValues: marshall({
            ":c": currentTime,
            ":e": expireAt
        }),
    };

    try {
        const data = await client.send(new UpdateItemCommand(params));
        const responseData = unmarshall(data.Attributes);
        console.log("Item updated successfully: %s", responseData);
        return responseData;
    } catch (err) {
        console.error("Error updating item:", err);
        throw err;
    }
}

// Example usage (commented out for testing)
// updateItem('your-table-name', 'your-partition-key-value', 'your-sort-key-value');
```
+  Pour plus de détails sur l'API, reportez-vous [UpdateItem](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/client/dynamodb/command/UpdateItemCommand)à la section *Référence des AWS SDK pour JavaScript API*. 

------
#### [ Python ]

**Kit SDK for Python (Boto3)**  

```
from datetime import datetime, timedelta

import boto3


def update_dynamodb_item(table_name, region, primary_key, sort_key):
    """
    Update an existing DynamoDB item with a TTL.
    :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.
    :return: Void (nothing)
    """
    try:
        # Create the DynamoDB resource.
        dynamodb = boto3.resource("dynamodb", region_name=region)
        table = dynamodb.Table(table_name)

        # Get the current time in epoch second format
        current_time = int(datetime.now().timestamp())

        # Calculate the expireAt time (90 days from now) in epoch second format
        expire_at = int((datetime.now() + timedelta(days=90)).timestamp())

        table.update_item(
            Key={"partitionKey": primary_key, "sortKey": sort_key},
            UpdateExpression="set updatedAt=:c, expireAt=:e",
            ExpressionAttributeValues={":c": current_time, ":e": expire_at},
        )

        print("Item updated successfully.")
    except Exception as e:
        print(f"Error updating item: {e}")


# Replace with your own values
update_dynamodb_item(
    "your-table-name", "us-west-2", "your-partition-key-value", "your-sort-key-value"
)
```
+  Pour plus de détails sur l'API, consultez [UpdateItem](https://docs.aws.amazon.com/goto/boto3/dynamodb-2012-08-10/UpdateItem)le *AWS manuel de référence de l'API SDK for Python (Boto3*). 

------

Les exemples de TTL présentés dans cette introduction illustrent une méthode permettant de garantir que seuls les éléments récemment mis à jour sont conservés dans une table. Les éléments mis à jour voient leur durée de vie prolongée, tandis que les éléments non mis à jour après leur création expirent et sont supprimés gratuitement, ce qui réduit le stockage utilisé et permet de maintenir les tables propres.

# Utilisation des éléments ayant expiré et de la durée de vie (TTL)
<a name="ttl-expired-items"></a>

Les éléments ayant expiré qui sont 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 ayant expiré ne sont plus valides et ne doivent pas être utilisées. S’ils ne sont pas exclus, 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.

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

## Exclusion des éléments ayant expiré des opérations de lecture
<a name="ttl-expired-items-filter"></a>

Pour les opérations de lecture telles que [Scan](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Scan.html) et [Query](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Query.html), une expression de filtre peut exclure les éléments ayant expiré qui sont en attente de suppression. Comme indiqué dans l’extrait de code suivant, l’expression de filtre peut exclure les éléments dont la durée de vie, ou TTL, est inférieure ou égale à l’heure actuelle. Par exemple, le code du kit SDK Python inclut une instruction d’affectation qui obtient l’heure actuelle sous forme de variable (`now`) et la convertit en `int` au format d’heure epoch.

Les exemples de code suivants montrent l’interrogation d’éléments TTL.

------
#### [ Java ]

**SDK pour Java 2.x**  
Expression filtrée par requête pour rassembler des éléments TTL dans une table DynamoDB à l'aide de. AWS SDK for Java 2.x  

```
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 java.util.Map;
import java.util.Optional;

        final QueryRequest request = QueryRequest.builder()
            .tableName(tableName)
            .keyConditionExpression(KEY_CONDITION_EXPRESSION)
            .filterExpression(FILTER_EXPRESSION)
            .expressionAttributeNames(expressionAttributeNames)
            .expressionAttributeValues(expressionAttributeValues)
            .build();

        try (DynamoDbClient ddb = dynamoDbClient != null
            ? dynamoDbClient
            : DynamoDbClient.builder().region(region).build()) {
            final QueryResponse response = ddb.query(request);
            System.out.println("Query successful. Found " + response.count() + " items that have not expired yet.");

            // Print each item
            response.items().forEach(item -> {
                System.out.println("Item: " + item);
            });

            return 0;
        } catch (ResourceNotFoundException e) {
            System.err.format(TABLE_NOT_FOUND_ERROR, tableName);
            throw e;
        } catch (DynamoDbException e) {
            System.err.println(e.getMessage());
            throw e;
        }
```
+  Pour plus d’informations sur l’API, consultez [Requête](https://docs.aws.amazon.com/goto/SdkForJavaV2/dynamodb-2012-08-10/Query) dans la *référence d’API AWS SDK for Java 2.x *. 

------
#### [ JavaScript ]

**SDK pour JavaScript (v3)**  
Expression filtrée par requête pour rassembler des éléments TTL dans une table DynamoDB à l'aide de. AWS SDK pour JavaScript  

```
import { DynamoDBClient, QueryCommand } from "@aws-sdk/client-dynamodb";
import { marshall, unmarshall } from "@aws-sdk/util-dynamodb";

export const queryFiltered = async (tableName, primaryKey, region = 'us-east-1') => {
    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;
    }
}

// Example usage (commented out for testing)
// queryFiltered('your-table-name', 'your-partition-key-value');
```
+  Pour plus d’informations sur l’API, consultez [Requête](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/client/dynamodb/command/QueryCommand) dans la *référence d’API AWS SDK pour JavaScript *. 

------
#### [ Python ]

**Kit SDK for Python (Boto3)**  
Expression filtrée par requête pour rassembler des éléments TTL dans une table DynamoDB à l'aide de. AWS SDK pour Python (Boto3)  

```
from datetime import datetime

import boto3


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")
```
+  Pour de plus amples informations sur l’API, consultez [Requête](https://docs.aws.amazon.com/goto/boto3/dynamodb-2012-08-10/Query) dans la *référence d’API AWS du kit SDK pour Python (Boto3)*. 

------

## Écriture conditionnelle sur les éléments ayant expiré
<a name="ttl-expired-items-conditional-write"></a>

Une expression conditionnelle peut être utilisée pour éviter les écritures sur les éléments ayant expiré. 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 tel est le cas, l’opération d’écriture se poursuit.

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

------
#### [ Java ]

**SDK pour Java 2.x**  
Mettez à jour de la TTL sur un élément DynamoDB existant dans une table, avec une condition.  

```
package com.amazon.samplelib.ttl;

import com.amazon.samplelib.CodeSampleUtils;
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.ConditionalCheckFailedException;
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 java.util.Map;
import java.util.Optional;

/**
 * Updates an item in a DynamoDB table with TTL attributes using a conditional expression.
 * This class demonstrates how to conditionally update TTL expiration timestamps.
 */
public class UpdateTTLConditional {

    private static final String USAGE =
        """
            Usage:
                <tableName> <primaryKey> <sortKey> <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.
                region (optional) - The AWS region that the Amazon DynamoDB table is located in. (Default: us-east-1)
            """;
    private static final int DAYS_TO_EXPIRE = 90;
    private static final int SECONDS_PER_DAY = 24 * 60 * 60;
    private static final String PRIMARY_KEY_ATTR = "primaryKey";
    private static final String SORT_KEY_ATTR = "sortKey";
    private static final String UPDATED_AT_ATTR = "updatedAt";
    private static final String EXPIRE_AT_ATTR = "expireAt";
    private static final String UPDATE_EXPRESSION = "SET " + UPDATED_AT_ATTR + "=:c, " + EXPIRE_AT_ATTR + "=:e";
    private static final String CONDITION_EXPRESSION = "attribute_exists(" + PRIMARY_KEY_ATTR + ")";
    private static final String SUCCESS_MESSAGE = "%s UpdateItem operation with TTL successful.";
    private static final String CONDITION_FAILED_MESSAGE = "Condition check failed. Item does not exist.";
    private static final String TABLE_NOT_FOUND_ERROR = "Error: The Amazon DynamoDB table \"%s\" can't be found.";

    private final DynamoDbClient dynamoDbClient;

    /**
     * Constructs an UpdateTTLConditional with a default DynamoDB client.
     */
    public UpdateTTLConditional() {
        this.dynamoDbClient = null;
    }

    /**
     * Constructs an UpdateTTLConditional with the specified DynamoDB client.
     *
     * @param dynamoDbClient The DynamoDB client to use
     */
    public UpdateTTLConditional(final DynamoDbClient dynamoDbClient) {
        this.dynamoDbClient = dynamoDbClient;
    }

    /**
     * Main method to demonstrate conditionally updating an item with TTL.
     *
     * @param args Command line arguments
     */
    public static void main(final String[] args) {
        try {
            int result = new UpdateTTLConditional().processArgs(args);
            System.exit(result);
        } catch (Exception e) {
            System.err.println(e.getMessage());
            System.exit(1);
        }
    }

    /**
     * Process command line arguments and conditionally update an item with TTL.
     *
     * @param args Command line arguments
     * @return 0 if successful, non-zero otherwise
     * @throws ResourceNotFoundException If the table doesn't exist
     * @throws DynamoDbException If an error occurs during the operation
     * @throws IllegalArgumentException If arguments are invalid
     */
    public int processArgs(final String[] args) {
        // Argument validation (remove or replace this line when reusing this code)
        CodeSampleUtils.validateArgs(args, new int[] {3, 4}, USAGE);

        final String tableName = args[0];
        final String primaryKey = args[1];
        final String sortKey = args[2];
        final Region region = Optional.ofNullable(args.length > 3 ? args[3] : null)
            .map(Region::of)
            .orElse(Region.US_EAST_1);

        // 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 + (DAYS_TO_EXPIRE * SECONDS_PER_DAY);

        // Create the key map for the item to update
        final Map<String, AttributeValue> keyMap = Map.of(
            PRIMARY_KEY_ATTR, AttributeValue.builder().s(primaryKey).build(),
            SORT_KEY_ATTR, AttributeValue.builder().s(sortKey).build());

        // Create the expression attribute values
        final Map<String, AttributeValue> expressionAttributeValues = Map.of(
            ":c", AttributeValue.builder().n(String.valueOf(currentTime)).build(),
            ":e", AttributeValue.builder().n(String.valueOf(expireDate)).build());

        final UpdateItemRequest request = UpdateItemRequest.builder()
            .tableName(tableName)
            .key(keyMap)
            .updateExpression(UPDATE_EXPRESSION)
            .conditionExpression(CONDITION_EXPRESSION)
            .expressionAttributeValues(expressionAttributeValues)
            .build();

        try (DynamoDbClient ddb = dynamoDbClient != null
            ? dynamoDbClient
            : DynamoDbClient.builder().region(region).build()) {
            final UpdateItemResponse response = ddb.updateItem(request);
            System.out.println(String.format(SUCCESS_MESSAGE, tableName));
            return 0;
        } catch (ConditionalCheckFailedException e) {
            System.err.println(CONDITION_FAILED_MESSAGE);
            throw e;
        } catch (ResourceNotFoundException e) {
            System.err.format(TABLE_NOT_FOUND_ERROR, tableName);
            throw e;
        } catch (DynamoDbException e) {
            System.err.println(e.getMessage());
            throw e;
        }
    }
}
```
+  Pour plus de détails sur l'API, reportez-vous [UpdateItem](https://docs.aws.amazon.com/goto/SdkForJavaV2/dynamodb-2012-08-10/UpdateItem)à la section *Référence des AWS SDK for Java 2.x API*. 

------
#### [ JavaScript ]

**SDK pour JavaScript (v3)**  
Mettez à jour de la 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";

export const updateItemConditional = async (tableName, partitionKey, sortKey, region = 'us-east-1', newAttribute = 'default-value') => {
    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;
    }
};

// Example usage (commented out for testing)
// updateItemConditional('your-table-name', 'your-partition-key-value', 'your-sort-key-value');
```
+  Pour plus de détails sur l'API, reportez-vous [UpdateItem](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/client/dynamodb/command/UpdateItemCommand)à la section *Référence des AWS SDK pour JavaScript API*. 

------
#### [ Python ]

**Kit SDK for Python (Boto3)**  
Mettez à jour de la TTL sur un élément DynamoDB existant dans une table, avec une condition.  

```
from datetime import datetime, timedelta

import boto3
from botocore.exceptions import ClientError


def update_dynamodb_item_ttl(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_ttl(
    "your-table-name",
    "us-east-1",
    "your-partition-key-value",
    "your-sort-key-value",
    "your-ttl-attribute-value",
)
```
+  Pour plus de détails sur l'API, consultez [UpdateItem](https://docs.aws.amazon.com/goto/boto3/dynamodb-2012-08-10/UpdateItem)le *AWS manuel de référence de l'API SDK for Python (Boto3*). 

------

## Identification des éléments supprimés dans DynamoDB Streams
<a name="ttl-expired-items-identifying"></a>

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

```
Records[<index>].userIdentity.type
"Service"

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

L’extrait JSON suivant montre la partie pertinente d’un seul enregistrement de flux :

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