Dans ce module, vous allez étudier des exemples simples d'extraction de plusieurs éléments dans un appel d'API avec DynamoDB. Vous apprendrez également à utiliser les index secondaires pour autoriser des modèles de requêtes supplémentaires dans vos tables DynamoDB.

Durée du module : 15 minutes


Dans le module 2, vous avez appris à extraire un seul livre à partir de la table DynamoDB en utilisant l'appel d'API GetItem. Ce modèle d'accès est utile, mais votre application doit également être capable d'extraire plusieurs éléments en même temps. Dans cet exemple, vous voulez extraire tous les livres écrits par John Grisham afin de les montrer aux utilisateurs. Dans l'étape 1 de ce module, vous allez utiliser l'API Query afin d'extraire tous les livres d'un même auteur.

L'appel d'API GetItem qui permet d'obtenir un seul livre, ainsi que l'appel d'API Query qui permet d'extraire tous les livres d'un même auteur utilisent la clé primaire qui est indiquée dans notre table Livres. Cependant, vous voulez pouvoir autoriser des modèles d'accès supplémentaires, comme extraire tous les livres d'une catégorie spécifique (par exemple, livres historiques ou biographies). La Catégorie ne fait pas partie de la clé primaire de votre table, mais vous pouvez créer un index secondaire pour autoriser des modèles d'accès supplémentaires. Vous créerez un index secondaire puis interrogerez cet index secondaire dans les étapes 2 et 3 de ce module.


  • Étape 1. Extraire plusieurs éléments avec une seule requête

    Lorsque votre table utilise une clé primaire composite, vous pouvez extraire tous les éléments avec la même clé de hachage en utilisant l'appel d'API Query. Pour votre application, cela signifie que vous pouvez extraire tous les livres disposant du même attribut Auteur.

    Exécutez la commande suivante dans le terminal AWS Cloud9.

    $ python query_items.py

    Cette commande permet d'exécuter le script suivant pour extraire tous les livres écrits par John Grisham.

    import boto3
    from boto3.dynamodb.conditions import Key
    
    # boto3 is the AWS SDK library for Python.
    # The "resources" interface allows for a higher-level abstraction than the low-level client interface.
    # For more details, go to http://boto3.readthedocs.io/en/latest/guide/resources.html
    dynamodb = boto3.resource('dynamodb', region_name='us-east-1')
    table = dynamodb.Table('Books')
    
    # When making a Query API call, you use the KeyConditionExpression parameter to specify the hash key on which you want to query.
    # You’re using the Key object from the Boto 3 library to specify that you want the attribute name ("Author")
    # to equal "John Grisham" by using the ".eq()" method.
    resp = table.query(KeyConditionExpression=Key('Author').eq('John Grisham'))
    
    print("The query returned the following items:")
    for item in resp['Items']:
        print(item)

    Après exécution du script, vous devrez voir deux livres de John Grisham : La Firme et L'Idéaliste.

    $ python query_items.py
    The query returned the following items:
    {'Title': 'The Firm', 'Formats': {'Hardcover': 'Q7QWE3U2', 'Paperback': 'ZVZAYY4F', 'Audiobook': 'DJ9KS9NM'}, 'Author': 'John Grisham', 'Category': 'Suspense'}
    {'Title': 'The Rainmaker', 'Formats': {'Hardcover': 'J4SUKVGU', 'Paperback': 'D7YF4FCX'}, 'Author': 'John Grisham', 'Category': 'Suspense'}

    Extraire plusieurs éléments en utilisant un seul appel dans DynamoDB est une pratique courante et facile à réaliser grâce à l'appel d'API Query.

  • Étape 2. Créer un index secondaire

    DynamoDB vous permet de créer des index secondaires afin de constituer des modèles d'accès aux données supplémentaires dans votre table. Les index secondaires sont un puissant moyen d'accroître la flexibilité des requêtes associées à une table DynamoDB.

    DynamoDB possède deux types d'index secondaires : les index secondaires globaux et les index secondaires locaux. Dans cette section, vous allez ajouter un index secondaire global à votre attribut Catégorie, ce qui vous permettra d'extraire tous les livres appartenant à une catégorie spécifique.

    Dans l'exemple suivant, le script permet d'ajouter un index secondaire à une table existante.

    import boto3
    
    # Boto3 is the AWS SDK library for Python.
    # You can use the low-level client to make API calls to DynamoDB.
    client = boto3.client('dynamodb', region_name='us-east-1')
    
    try:
        resp = client.update_table(
            TableName="Books",
            # Any attributes used in your new global secondary index must be declared in AttributeDefinitions
            AttributeDefinitions=[
                {
                    "AttributeName": "Category",
                    "AttributeType": "S"
                },
            ],
            # This is where you add, update, or delete any global secondary indexes on your table.
            GlobalSecondaryIndexUpdates=[
                {
                    "Create": {
                        # You need to name your index and specifically refer to it when using it for queries.
                        "IndexName": "CategoryIndex",
                        # Like the table itself, you need to specify the key schema for an index.
                        # For a global secondary index, you can use a simple or composite key schema.
                        "KeySchema": [
                            {
                                "AttributeName": "Category",
                                "KeyType": "HASH"
                            }
                        ],
                        # You can choose to copy only specific attributes from the original item into the index.
                        # You might want to copy only a few attributes to save space.
                        "Projection": {
                            "ProjectionType": "ALL"
                        },
                        # Global secondary indexes have read and write capacity separate from the underlying table.
                        "ProvisionedThroughput": {
                            "ReadCapacityUnits": 1,
                            "WriteCapacityUnits": 1,
                        }
                    }
                }
            ],
        )
        print("Secondary index added!")
    except Exception as e:
        print("Error updating table:")
        print(e)

    La création d'un index secondaire global a beaucoup de points communs avec la création d'une table. Indiquez le nom de l'index, les attributs qu'il contiendra, son schéma de clé et le débit qui lui est alloué (capacité maximale qu'une application peut consommer dans une table ou un index). Le débit alloué à chaque index est séparé du débit alloué à une table. Cela vous permet de définir précisément le débit nécessaire afin de répondre aux besoins de votre application.

    Exécutez la commande suivante dans votre terminal pour ajouter un index secondaire global.

    $ python add_secondary_index.py

    Ce script ajoute un index secondaire global appelé CategoryIndex à votre table Livres.

  • Étape 3. Interroger un index secondaire

    Maintenant que vous avez créé CategoryIndex, vous pouvez l'utiliser pour extraire tous les livres appartenant à une catégorie spécifique. Utiliser un index secondaire pour interroger une table revient à utiliser l'appel d'API Query. Maintenant, ajoutez le nom de l'index à l'appel d'API.

    Lorsque vous ajoutez un index secondaire global à une table existante, DynamoDB remplit l'index de façon asynchrone avec les éléments existants de la table. L'index est ensuite disponible pour interroger tous les éléments qui ont été remplis. Le temps de remplissage varie en fonction de la taille de la table.

    Vous pouvez utiliser le script query_with_index.py pour interroger le nouvel index. Exécutez le script dans votre terminal avec la commande suivante.

    $ python query_with_index.py

    Cette commande permet d'exécuter le script suivant pour extraire tous les livres disponibles qui appartiennent à la Catégorie Suspense.

    import time
    
    import boto3
    from boto3.dynamodb.conditions import Key
    
    # Boto3 is the AWS SDK library for Python.
    # The "resources" interface allows for a higher-level abstraction than the low-level client interface.
    # For more details, go to http://boto3.readthedocs.io/en/latest/guide/resources.html
    dynamodb = boto3.resource('dynamodb', region_name='us-east-1')
    table = dynamodb.Table('Books')
    
    # When adding a global secondary index to an existing table, you cannot query the index until it has been backfilled.
    # This portion of the script waits until the index is in the “ACTIVE” status, indicating it is ready to be queried.
    while True:
        if not table.global_secondary_indexes or table.global_secondary_indexes[0]['IndexStatus'] != 'ACTIVE':
            print('Waiting for index to backfill...')
            time.sleep(5)
            table.reload()
        else:
            break
    
    # When making a Query call, you use the KeyConditionExpression parameter to specify the hash key on which you want to query.
    # If you want to use a specific index, you also need to pass the IndexName in our API call.
    resp = table.query(
        # Add the name of the index you want to use in your query.
        IndexName="CategoryIndex",
        KeyConditionExpression=Key('Category').eq('Suspense'),
    )
    
    print("The query returned the following items:")
    for item in resp['Items']:
        print(item)

    Notez qu'une partie du script attend que l'index soit disponible pour lancer l'interrogation.

    Vous obtiendrez la sortie suivante dans votre terminal.

    $ python query_with_index.py
    The query returned the following items:
    {'Title': 'The Firm', 'Formats': {'Hardcover': 'Q7QWE3U2', 'Paperback': 'ZVZAYY4F', 'Audiobook': 'DJ9KS9NM'}, 'Author': 'John Grisham', 'Category': 'Suspense'}
    {'Title': 'The Rainmaker', 'Formats': {'Hardcover': 'J4SUKVGU', 'Paperback': 'D7YF4FCX'}, 'Author': 'John Grisham', 'Category': 'Suspense'}
    {'Title': 'Along Came a Spider', 'Formats': {'Hardcover': 'C9NR6RJ7', 'Paperback': '37JVGDZG', 'Audiobook': '6348WX3U'}, 'Author': 'James Patterson', 'Category': 'Suspense'}

    La requête remonte trois livres écrits par deux auteurs différents. Ceci est un modèle d'interrogation qui aurait été difficile avec le schéma de clé principale de votre table, mais qui est facile à implémenter grâce à la puissance des index secondaires.


    Dans le prochain module, vous apprendrez à mettre à jour les attributs d'un élément existant dans une table en utilisant l'API UpdateItem