![](/img/trans.png)
[英]DynamoDB FilterExpression with multiple condition python and boto3
[英]DynamoDB Query FilterExpression Multiple Condition Chaining Python
我正在嘗試根據用戶提供的特定屬性的參數(我們稱之為“ ATTRIBUTE1
”)以編程方式在 Python 中為 DynamoDB 查詢創建 FilterExpression。
我需要過濾的所有用戶提供的參數都在列表中。 例如: ['Parameter1', 'Parameter2']
然后將采用Attr('ATTRIBUTE1').eq(PARAMETER1)&Attr.('ATTRIBUTE1').eq(PARAMETER2)
如何以編程方式為我的 FilterExpression 創建一個 Attr 像上面那樣基於用戶提供的參數數量的變化?
有時我可能有['Parameter1']
和另一個時間我可能有['Parameter1', 'Parameter2', 'Parameter3']
需要變成Attr('ATTRIBUTE1').eq('Parameter1')
和Attr('ATTRIBUTE1').eq('Parameter1')&Attr('ATTRIBUTE1').eq('Parameter2')&Attr('ATTRIBUTE1').eq('Parameter3')
分別。
我還沒有找到解決方案,希望得到任何指導。 提前致謝。
您可以嘗試以下操作。 我通過查詢參數循環來構建 dynamodb 條件。
if event.get('queryStringParameters'):
query_params = event.get('queryStringParameters')
for query_param, value in query_params.items():
if query_param == 'attribute1':
filter_expression_list.append(Attr('attribute1').gte(value))
if query_param == 'attribute2':
filter_expression_list.append(Attr('attribute2').eq(value))
if query_param == 'attribute3':
filter_expression_list.append(Attr('attribute3').eq(value))
FilterExpression = get_filter_expression(filter_expression_list)
更新:
可以使用以下代碼獲取過濾器表達式。 這將處理有 2 個或 2 個以上表達式的情況
def get_filter_expression(filter_expression_list):
filter_expression = None
first = True
for filter in filter_expression_list:
if first:
filter_expression = filter
first = False
else:
filter_expression = filter_expression & filter
return filter_expression
這是我能夠使其工作的緊湊方式:
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()])))
例如, filters
將是一個像這樣的dict
:
{
'Status': 'Approved',
'SubmittedBy': 'JackCasey'
}
字符串形式的 FilterExpression 和 ExpressionAttributeValues 的組合可以工作,請考慮以下示例:
attrs = ["attribute1", "attribute2", "attribute3"]
user_input = ["parameter1", "paramater2", "parameter3"]
ExpressionAttributeValues = {}
FilterExpression = "";
for index, input in enumerate(attrs):
if(len(attrs)-1 == index): FilterExpression += input+"=:"+input
else: FilterExpression += input+" = :"+input + " AND ";
for index, input in enumerate(user_input):
AttrName = ":" + attrs[index]
ExpressionAttributeValues[AttrName] = {
"S" : input
}
print(ExpressionAttributeValues)
print(FilterExpression)
然后你可以在你的查詢中使用這兩個,更多在這里http://boto3.readthedocs.io/en/latest/reference/services/dynamodb.html#client
一種緊湊的 Pythonic 方法可能是管理字典中的標准,避免循環以支持理解,並使用字符串格式方法:
criteria = {'my_key1': 'my_value1', 'my_key2': 'my_value2'}
FilterExpression = ' AND '.join(['{0}=:{0}'.format(k) for k, v in criteria.items()])
ExpressionAttributeValues = {':{}'.format(k): {'S': v} for k, v in criteria.items()}
i = 0
for key, val in attr_value_dic.items():
if i == 0:
filterCondition = Attr(key).eq(val)
filterConidtion = filterCondition & Attr(key).eq(val)
i = i + 1
response = table.query(
KeyConditionExpression=Key(partition_key).eq(search_value)
,FilterExpression=filterCondition
)
我在python中鏈接多個過濾器表達式的解決方案。
from boto3.dynamodb.conditions import Key, Attr
...
users_table_dynamo.query(
KeyConditionExpression=Key('pk').eq('SC#' + sc_id) & Key('sk').begins_with("GA#"),
FilterExpression=eval("Attr('attribute1').eq('value1') & Attr('attribute2').eq('value2') & Attr('attribute3').eq('value3')"))
我也可以寫這樣的東西,用於動態表達式創建:
def constructFilterExpression(tag_ids):
expression = ""
for idx, item in enumerate(tag_ids):
if idx == 0:
expression += f"Attr('user_tag_id').eq('{str(item)}')"
else:
expression += f" & Attr('user_tag_id').eq('{str(item)}')"
return expression
所以最后我的查詢是:
filterExpression = constructFilterExpression(tag_ids)
item = users_table_dynamo.query(
KeyConditionExpression=Key('pk').eq('SC#' + scenario_id) & Key('sk').begins_with("AT#"),
FilterExpression=eval(filterExpression),
ProjectionExpression="article_id")
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.