Сканирование Динамо БД с Boto3 для массива словаря - PullRequest
3 голосов
/ 11 июня 2019

Требуется проверить базу данных Dynamo, имеющую записи со списком объектов словаря.Ниже приведены мои примеры данных

'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: Произошла ошибка (ValidationException) при вызове операции сканирования: значение, предоставленное в ExpressionAttributeValues, не используется в выражениях: keys: {: itemVal}

Ответы [ 3 ]

2 голосов
/ 11 июня 2019

Функция contains позволяет вам только искать строку в строке или строку в наборе. Вам нужно будет реструктурировать ваши данные, или вам нужно будет отфильтровать результаты вашего сканирования в вашем коде Python.

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

1 голос
/ 19 июня 2019

Во втором фрагменте кода 'itemVal' это просто строка, и она не соответствует :itemVal из ExpressionAttributeValues.В формате, который вы предлагаете, вы можете избавиться от ExpressionAttributeValues и вместо этого использовать что-то вроде этого:

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

response = table.scan(
    FilterExpression=Attr('toAddr').contains(json.dumps(itemVal))
) 
0 голосов
/ 28 июня 2019

@ tommy, Ваш ответ почти правильный, за исключением того, что мы не должны использовать json.dumps

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

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

Вышеуказанный помог отсканировать результаты.

...