Scan Dynamo DB with boto3 for array of dictionary

Viewed 4060

Need to scan Dynamo DB having records with list of dictionary objects. Below is my sample data

'toAddr': [{'type': 'email', 'address': 'aaa@gmail.com'}, {'type': 'email', 'address': 'bbb@gmail.com'}]}

Below lines of code would do the needful for me.

client = boto3.resource('dynamodb')
table = client.Table(table_name)
response = table.scan(FilterExpression="contains (#items, :itemVal)",
                      ExpressionAttributeNames={"#items": "toAddr"},
                      ExpressionAttributeValues={":itemVal":{"address":"aaa@gmail.com",
                                                              type":"email"}})

However i would like to build the filter Expression in below format

response = table.scan(FilterExpression=Attr('toAddr').contains('itemVal'),
                      ExpressionAttributeValues={":itemVal":{"address":"aaa@gmail.com",
                                                    "type":"email"}}) 

But this would result in an error

botocore.exceptions.ClientError: An error occurred (ValidationException) when calling the Scan operation: Value provided in ExpressionAttributeValues unused in expressions: keys: {:itemVal}

3 Answers

In the second code snippet 'itemVal' is just a string and it is not matched with :itemVal from ExpressionAttributeValues. In the format you are proposing you can get rid of ExpressionAttributeValues and instead use something like this:

itemVal = {"address": "aaa@gmail.com", "type": "email"}

response = table.scan(
    FilterExpression=Attr('toAddr').contains(json.dumps(itemVal))
) 

@tommy, Your answer is almost correct except we should not use json.dumps

itemVal = {"address": "aaa@gmail.com", "type": "email"}

response = table.scan(
    FilterExpression=Attr('toAddr').contains((itemVal)
) 

The above one helped to scan results.

Related