In diesem Modul werden einige einfache Beispiele zum Abrufen mehrerer Elemente in einem API-Aufruf mit DynamoDB beschrieben. Außerdem erfahren Sie, wie Sie Sekundärindizes verwenden können, um zusätzliche Abfragemuster in Ihren DynamoDB-Tabellen zu aktivieren.

Veranschlagte Zeit für das Modul: 15 Minuten


In Modul 2 haben Sie gesehen, wie Sie ein einzelnes Buch mithilfe des GetItem-API-Aufrufs aus einer DynamoDB-Tabelle abrufen. Dieses Zugriffsmuster ist nützlich, aber Ihre Anwendung muss auch in der Lage sein, mehrere Elemente in einem Aufruf abzurufen. Beispielsweise möchten Sie vielleicht alle Bücher abrufen, die von John Grisham geschrieben wurden, damit Sie diese den Benutzern anzeigen können. In Schritt 1 dieses Moduls verwenden Sie die Abfrage-API, um alle Bücher eines bestimmten Autors abzurufen.

Sowohl der GetItem-API-Aufruf zum Abrufen eines einzelnen Buches als auch der Query-API-Aufruf zum Abrufen aller Bücher eines bestimmten Autors verwenden den angegebenen Primärschlüssel in Ihrer Bücher-Tabelle. Möglicherweise möchten Sie jedoch zusätzliche Zugriffsmuster aktivieren, z. B. das Abrufen aller Bücher in einer bestimmten Kategorie, wie z. B. Geschichte oder Biografie. Kategorie ist nicht Teil des Primärschlüssels Ihrer Tabelle. Sie können jedoch einen Sekundärindex erstellen, um zusätzliche Zugriffsmuster zu ermöglichen. Sie werden einen Sekundärindex erstellen und diesen dann in Schritt 2 und 3 dieses Moduls abfragen.


  • Schritt 1. Mehrere Elemente mit einer Abfrage abrufen

    Wenn Ihre Tabelle einen zusammengesetzten Primärschlüssel verwendet, können Sie mithilfe des Abfrage-API-Aufrufs alle Elemente mit demselben Hash-Schlüssel abrufen. Für Ihre Anwendung bedeutet dies, dass Sie alle Bücher mit demselben Autor-Attribut abrufen können.

    Führen Sie im AWS Cloud9-Terminal den folgenden Befehl aus.

    $ python query_items.py

    Dieser Befehl führt das folgende Skript aus, welches alle von John Grisham geschriebenen Bücher abruft.

    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)

    Nachdem Sie das Skript ausgeführt haben, sollten Sie zwei Bücher von John Grisham sehen: Die Firma und Der Regenmacher.

    $ 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'}

    Das Abrufen mehrerer Elemente mit einem einzigen Aufruf in DynamoDB ist ein gängiges Muster und mit dem Abfrage-API-Aufruf einfach durchzuführen.

  • Schritt 2. Erstellen eines sekundären Indexes

    Mit DynamoDB können Sie Sekundärindizes erstellen, um zusätzliche Datenzugriffsmuster in Ihrer Tabelle zu berücksichtigen. Bei Sekundärindizes handelt es sich um eine leistungsstarke Möglichkeit, einer DynamoDB-Tabelle Abfrageflexibilität hinzuzufügen.

    DynamoDB verfügt über zwei Arten von Sekundärindizes: globale Sekundärindizes und lokale Sekundärindizes. In diesem Abschnitt fügen Sie Ihrem Kategorie-Attribut einen globalen Sekundärindex hinzu, mit dem Sie alle Bücher in einer bestimmten Kategorie abrufen können.

    Das folgende Beispielskript fügt einer vorhandenen Tabelle einen globalen Sekundärindex hinzu.

    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)

    Das Erstellen eines globalen Sekundärindexes ist mit dem Erstellen einer Tabelle vergleichbar. Sie geben einen Namen für den Index, die Attribute im Index, das Schlüsselschema des Index sowie den bereitgestellten Durchsatz an (die maximale Kapazität, die eine Anwendung aus einer Tabelle oder einem Index verbrauchen kann). Der bereitgestellte Durchsatz für jeden Index ist unabhängig vom bereitgestellten Durchsatz für eine Tabelle. Auf diese Weise können Sie den Durchsatz detailliert definieren, um die Anforderungen Ihrer Anwendung zu erfüllen.

    Führen Sie den folgenden Befehl in Ihrem Terminal aus, um Ihren globalen Sekundärindex hinzuzufügen.

    $ python add_secondary_index.py

    Dieses Skript fügt Ihrer Bücher-Tabelle einen globalen Sekundärindex namens CategoryIndex hinzu.

  • Schritt 3. Abfragen eines sekundären Indexes

    Jetzt, wo Sie den CategoryIndex haben, können Sie damit alle Bücher mit einer bestimmten Kategorie abrufen. Die Verwendung eines Sekundärindexes zum Abfragen einer Tabelle ähnelt der Verwendung des Abfrage-API-Aufrufs. Jetzt fügen Sie den Indexnamen zum API-Aufruf hinzu.

    Wenn Sie einer vorhandenen Tabelle einen globalen Sekundärindex hinzufügen, füllt DynamoDB den Index asynchron mit den vorhandenen Elementen in der Tabelle. Der Index kann abgefragt werden, nachdem alle Elemente nachgefüllt wurden. Die Zeit zum Auffüllen hängt von der Größe der Tabelle ab.

    Sie können das Skript query_with_index.py verwenden, um den neuen Index abzufragen. Führen Sie dieses Skript mit dem folgenden Befehl in Ihrem Terminal aus:

    $ python query_with_index.py

    Dieser Befehl führt das folgende Skript aus, um alle Bücher im Geschäft abzurufen, die die Kategorie Spannung haben.

    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)

    Beachten Sie, dass ein Teil des Skripts wartet, bis der Index zum Abfragen verfügbar ist.

    Sie sollten die folgende Ausgabe in Ihrem Terminal sehen:

    $ 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'}

    Die Abfrage gibt drei Bücher von zwei verschiedenen Autoren zurück. Dies ist ein Abfragemuster, das mit dem Hauptschlüsselschema Ihrer Tabelle schwierig gewesen wäre, aber mit der Leistung von Sekundärindizes einfach zu implementieren ist.


    Im nächsten Modul erfahren Sie, wie Sie die Attribute eines vorhandenen Elements in einer Tabelle mithilfe der UpdateItem-API aktualisieren.