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).