使用 boto3 扫描 Dynamo DB 以获取字典数组

Scan Dynamo DB with boto3 for array of dictionary

需要扫描具有字典对象列表记录的 Dynamo DB。 下面是我的样本数据

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

下面几行代码可以满足我的需要。

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"}})

但是我想构建以下格式的过滤器表达式

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

但这会导致错误

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

contains函数只允许您在字符串中搜索字符串或在集合中搜索字符串。您将需要重组数据,或者需要在 python 代码中过滤扫描结果。

https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html

在第二个代码片段中,'itemVal' 只是一个字符串,它与 ExpressionAttributeValues 中的 :itemVal 不匹配。在您建议的格式中,您可以摆脱 ExpressionAttributeValues 而使用类似这样的格式:

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

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

@tommy,你的回答几乎是正确的,除了我们不应该使用 json.dumps

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

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

以上帮助扫描结果。