How do we query on a secondary index of dynamodb using boto3?

Amazon Web-ServicesAmazon DynamodbBoto3

Amazon Web-Services Problem Overview


Is there a way at all to query on the global secondary index of dynamodb using boto3. I dont find any online tutorials or resources.

Amazon Web-Services Solutions


Solution 1 - Amazon Web-Services

You need to provide an IndexName parameter for the query function.

This is the name of the index, which is usually different from the name of the index attribute (the name of the index has an -index suffix by default, although you can change it during table creation). For example, if your index attribute is called video_id, your index name is probably video_id-index.

import boto3
from boto3.dynamodb.conditions import Key
dynamodb = boto3.resource('dynamodb')
table = dynamodb.Table('videos')
video_id = 25
response = table.query(
    IndexName='video_id-index',
    KeyConditionExpression=Key('video_id').eq(video_id)
)

To check the index name, go to the Indexes tab of the table on the web interface of AWS. You'll need a value from the Name column.

Solution 2 - Amazon Web-Services

For anyone using the boto3 client, below example should work:

import boto3    

# for production
client = boto3.client('dynamodb')

# for local development if running local dynamodb server
client = boto3.client(
   'dynamodb',
   region_name='localhost',
   endpoint_url='http://localhost:8000'
)

resp = client.query(
   TableName='UsersTabe',
   IndexName='MySecondaryIndexName',
   ExpressionAttributeValues={
       ':v1': {
           'S': '[email protected]',
       },
   },
   KeyConditionExpression='emailField = :v1',
)

# will always return list
items = resp.get('Items')

first_item = items[0]

Solution 3 - Amazon Web-Services

Adding the updated technique:

    import boto3
    from boto3.dynamodb.conditions import Key, Attr

    dynamodb = boto3.resource(
         'dynamodb',
         region_name='localhost',
         endpoint_url='http://localhost:8000'
    )

    table = dynamodb.Table('userTable')

    attributes = table.query(
        IndexName='UserName',
        KeyConditionExpression=Key('username').eq('jdoe')
    )
    if 'Items' in attributes and len(attributes['Items']) == 1:
        attributes = attributes['Items'][0]

Solution 4 - Amazon Web-Services

There are so many questions like this because calling dynamo through boto3 is not intuitive. I use dynamof library to make things like this a lot more common sense. Using dynamof the call looks like this.

from dynamof.operations import query
from dynamof.conditions import attr

query(
    table_name='users',
    conditions=attr('role').equals('admin'),
    index_name='role_lookup_index')

https://github.com/rayepps/dynamof

disclaimer: I wrote dynamof

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionZZzzZZzzView Question on Stackoverflow
Solution 1 - Amazon Web-ServicesAttila TanyiView Answer on Stackoverflow
Solution 2 - Amazon Web-ServicesGWedView Answer on Stackoverflow
Solution 3 - Amazon Web-ServicesMatt HolmesView Answer on Stackoverflow
Solution 4 - Amazon Web-ServicesrayeppsView Answer on Stackoverflow