python – Dynamodb scan() using FilterExpression
python – Dynamodb scan() using FilterExpression
This is because you used Pythons 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).
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()]))
python – Dynamodb scan() using FilterExpression
Using parts from each of the above answers, heres a compact way I was able to get this working:
from functools import reduce
from boto3.dynamodb.conditions import Key, And
response = table.scan(FilterExpression=reduce(And, ([Key(k).eq(v) for k, v in filters.items()])))
Allows filtering upon multiple conditions in filters
as a dict
. For example:
{
Status: Approved,
SubmittedBy: JackCasey
}