In questo modulo, verranno illustrati alcuni semplici esempi di recupero di più elementi in un'unica chiamata API con DynamoDB. Scoprirai anche come utilizzare gli indici secondari per abilitare i modelli aggiuntivi di query sulle tabelle DynamoDB.

Tempo necessario per completare il modulo: 15 minuti


Nel Modulo 2, hai imparato a recuperare un unico libro da una tabella DynamoDB utilizzando la chiamata API GetItem. Questo modello di accesso è utile, ma la tua applicazione deve anche poter essere in grado di recuperare più elementi con un'unica chiamata. Potresti, ad esempio, voler recuperare tutti i libri scritti da John Grisham per consentire agli utenti di visualizzarli. Nella Fase 1 di questo modulo, utilizzi l'API Query per recuperare tutti i libri di un autore specifico.

Sia la chiamata API GetItem per ottenere un unico libro che la chiamata API Query per recuperare tutti i libri di uno stesso autore utilizzano la chiave principale specificata nella tua tabella Libri. Tuttavia, potresti voler abilitare altri modelli di accesso aggiuntivi, come il recupero di tutti i libri di una particolare categoria come storia o geografia. Categoria non fa parte della chiave principale della nostra tabella, ma puoi creare un indice secondario per consentire modelli di accesso aggiuntivi. Creerai quindi un indice secondario e interrogherai tale indice secondario nelle Fasi 2 e 3 di questo modulo.


  • Fase 1. Recupero di più elementi con una query

    Quando la tua tabella utilizza una chiave principale composta, puoi recuperare tutti gli elementi con la stessa chiave hash utilizzando la chiamata API Query. Per la tua applicazione, ciò significa che puoi recuperare tutti i libri con lo stesso attributo Autore.

    Nel terminale AWS Cloud9, esegui il comando seguente.

    $ python query_items.py

    Questo comando esegue lo script seguente che recupera tutti i libri scritti da 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)

    Una volta eseguito lo script, dovresti vedere due libri di John Grisham: Il socio e L'uomo della pioggia.

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

    Recuperare più elementi con un'unica chiamata in DynamoDB è un modello comune e facile da eseguire con la chiamata API Query.

  • Fase 2. Creazione di un indice secondario

    DynamoDB ti consente di creare indici secondari per tenere conto di modelli aggiuntivi di accesso ai dati della tua tabella. Gli indici secondari sono un metodo potente per aggiungere flessibilità di query a una tabella DynamoDB.

    DynamoDB presenta due tipi di indici secondari: indici secondari globali e indici secondari locali. In questa sezione, imparerai ad aggiungere un indice secondario al tuo attributo Categoria per poter recuperare tutti i libri di una categoria specifica.

    Lo script di esempio seguente consente di aggiungere un indice secondario globale a una tabella esistente.

    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)

    Creare un indice secondario globale ha molti aspetti in comune con la creazione di una tabella. Devi specificare il nome dell'indice, gli attributi che saranno contenuti nell'indice, lo schema chiave dell'indice e il throughput assegnato (la capacità massima che un'applicazione può utilizzare da una tabella o da un indice). Il throughput assegnato in ciascun indice è diverso dal throughput assegnato in una tabella. Ciò consente di definire la granularità del throughput per soddisfare le esigenze della tua applicazione.

    Esegui il comando seguente nel tuo terminale per aggiungere l'indice secondario globale.

    $ python add_secondary_index.py

    Lo script aggiunge un indice secondario globale chiamato CategoryIndex alla tua tabella Libri.

  • Fase 3. Esecuzione di query di un indice secondario

    Ora che hai l'indice CategoryIndex, puoi utilizzarlo per recuperare tutti i libri di una categoria specifica. L'uso di un indice secondario per eseguire una query di una tabella è simile all'uso della chiamata API Query. Devi ora aggiungere il nome dell'indice alla chiamata API.

    Quando aggiungi un indice secondario globale a una tabella esistente, DynamoDB recupera le informazioni in modo asincrono dall'indice con gli elementi presenti nella tabella. Quando tutte le informazioni sono state recuperate, l'indice è disponibile per l'esecuzione della query. Il tempo per recuperare le informazioni varia in base alle dimensioni della tabella.

    Puoi utilizzare lo script query_with_index.py per eseguire la query a fronte del nuovo indice. Esegui lo script nel tuo terminale con il comando seguente.

    $ python query_with_index.py

    Questo comando esegue lo script seguente per recuperare tutti i libri nel negozio con Categoria 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)

    Va notato che una parte dello script attende fino a quando l'indice è disponibile per l'esecuzione di query.

    Dovresti visualizzare l'output seguente nel terminale.

    $ 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 query restituisce tre libri di due autori diversi. Questo è un modello di query che sarebbe risultato difficile con lo schema chiave principale della tabella ma che è invece facile implementare con la potenza degli indici secondari.


    Nel modulo successivo, scoprirai come aggiornare gli attributi di un elemento presente in una tabella utilizzando l'API UpdateItem