DynamoDB - How to query nested boto3 attribute

I am following python DynamoDB tutorial. This step shows you how to query a table based on a specific key: http://docs.aws.amazon.com/amazondynamodb/latest/gettingstartedguide/GettingStarted.Python.04.html .

Here is the code for this request:

from __future__ import print_function # Python 2/3 compatibility
import boto3
import json
import decimal
from boto3.dynamodb.conditions import Key, Attr

# Helper class to convert a DynamoDB item to JSON.
class DecimalEncoder(json.JSONEncoder):
    def default(self, o):
        if isinstance(o, decimal.Decimal):
            return str(o)
        return super(DecimalEncoder, self).default(o)

dynamodb = boto3.resource('dynamodb', region_name='us-west-2', endpoint_url="http://localhost:8000")

table = dynamodb.Table('Movies')

print("Movies from 1992 - titles A-L, with genres and lead actor")

response = table.query(
    ProjectionExpression="#yr, title, info.genres, info.actors[0]",
    ExpressionAttributeNames={ "#yr": "year" }, # Expression Attribute Names for Projection Expression only.
    KeyConditionExpression=Key('year').eq(1992) & Key('title').between('A', 'L')
)

for i in response[u'Items']:
    print(json.dumps(i, cls=DecimalEncoder))

      

Sample response:

{
    "title": "Juice",
    "year": "1992",
    "info": {
        "actors": [
            "Omar Epps"
        ],
        "genres": [
            "Crime",
            "Drama",
            "Thriller"
        ]
    }
}

      

The table has two key attributes 'title' and 'year' and a nested attribute 'info'. What I am trying to do is query the database and filter movies by genre, for example, get all movies about dramas. I'm not sure how to do this as the key is nested in the information.

I tried to get all drama movies since 1992 like this but it came out empty.

response = table.query(
    KeyConditionExpression=Key('year').eq(1992),
    FilterExpression=Attr('info.genres').eq('Drama')
)

      

How do I properly filter this request using the nested info attribute?

+3


source to share


1 answer


You can use contains

to filter data from the List type .

genres - an attribute stored as a List attribute internally info

, which is a map data type



FilterExpression=Attr('info.genres').contains('Drama')

      

+4


source







All Articles