Dynamodb scan() using FilterExpression

Dynamodb scan() using FilterExpression

For multiple filters, you can use this approach:

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

filters = dict()
filters['Date'] = "2017-06-21"
filters['Shift'] = "3rd"

response = table.scan(FilterExpression=And(*[(Key(key).eq(value)) for key, value in filters.items()]))

This is because you used Python's and keyword in your expression, instead of the & operator.

If a and b are both considered True, a and b returns the latter, b:

>>> 2 and 3
3

If any of them is False, or if both of them are, the first False object is returned:

>>> 0 and 3
0
>>> 0 and ''
0
>>> 

The general rule is, and returns the first object that allows it to decide the truthiness of the whole expression.

Python objects are always considered True in boolean context. So, your expression:

Attr("Date").eq(date) and Attr("Shift").eq(shift)

will evaluate as the last True object, that is:

Attr("Shift").eq(shift)

which explains why you only filtered on the shift.

You need to use the & operator. It usually means "bitwise and" between integers in Python, it is redefined for Attr objects to mean what you want: "both conditions".

So you must use the "bitwise and":

FilterExpression=Attr("Date").eq(date) & Attr("Shift").eq(shift)

According to the documentation,

You are also able to chain conditions together using the logical operators: & (and), | (or), and ~ (not).