Tor*_*byn 7 python python-2.7 amazon-dynamodb
首先发表在Stack上,这是使用Python和使用DynamoDB进行编程的新手,但是我只是试图对我的表进行扫描,以返回基于两个预定义属性的结果。
---这是我的Python代码段---
shift = "3rd"
date = "2017-06-21"
if shift != "":
response = table.scan(
FilterExpression=Attr("Date").eq(date) and Attr("Shift").eq(shift)
)
Run Code Online (Sandbox Code Playgroud)
我的DynamoDB有4个字段。

现在,针对该问题,在运行时,我将获得两个表条目,而我仅应获得第一个条目...根据我的扫描标准,该条目具有“无安全问题”。
---这是我的DynamoDB返回结果---
[
{
"Shift": "3rd",
"Safety": "No safety issues",
"Date": "2017-06-21",
"ID": "2"
},
{
"Shift": "3rd",
"Safety": "Cut Finger",
"Date": "2017-06-22",
"ID": "4"
}
]
Run Code Online (Sandbox Code Playgroud)
返回的项目:2
我相信,通过将FilterExpression与逻辑“和”一起应用,可以指定扫描操作正在查找满足两个条件的条目,因为我使用了“和”。
可能是因为在两个条目中都找到了“ shift”属性“ 3rd”吗?如何确保它根据两个条件都满足而返回条目,而不仅仅是给出一种属性类型的结果?
我觉得这很简单,但是我在以下位置查看了可用的文档:http : //boto3.readthedocs.io/en/latest/reference/services/dynamodb.html#DynamoDB.Table.scan,仍然遇到问题。任何帮助将不胜感激!
PS我试图使文章简单易懂(不包括我的所有程序代码),但是,如果需要其他信息,我可以提供!
这是因为您and在表达式中使用了Python的关键字,而不是&运算符。
如果a和b都认为True,a and b返回后,b:
>>> 2 and 3
3
Run Code Online (Sandbox Code Playgroud)
如果它们中的任何一个是False,或者如果它们两个都是,False则返回第一个对象:
>>> 0 and 3
0
>>> 0 and ''
0
>>>
Run Code Online (Sandbox Code Playgroud)
一般规则是,and返回允许其确定整个表达式的真实性的第一个对象。
始终True在布尔上下文中考虑Python对象。所以,你的表情:
Attr("Date").eq(date) and Attr("Shift").eq(shift)
Run Code Online (Sandbox Code Playgroud)
将评估为最后一个True对象,即:
Attr("Shift").eq(shift)
Run Code Online (Sandbox Code Playgroud)
这就解释了为什么您只对班次进行过滤。
您需要使用&运算符。它通常在Python中的整数之间表示“按位与”,为Attr对象重新定义它以表示您想要的内容:“两个条件”。
因此,您必须使用“按位与”:
FilterExpression=Attr("Date").eq(date) & Attr("Shift").eq(shift)
Run Code Online (Sandbox Code Playgroud)
根据文档,
您还可以使用逻辑运算符将条件链接在一起:&(和),|。(或)和〜(不是)。
Dynamodb scan() 使用 FilterExpression
对于多个过滤器,您可以使用这种方法:
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()]))
Run Code Online (Sandbox Code Playgroud)
扩展 Maxime Paille 的答案,这涵盖了仅存在一个过滤器与存在多个过滤器时的情况。
from boto3.dynamodb.conditions import And, Attr
from functools import reduce
from operator import and_
filters = dict()
filters['Date'] = "2017-06-21"
filters['Shift'] = "3rd"
table.scan("my-table", **build_query_params(filters))
def build_query_params(filters):
query_params = {}
if len(filters) > 0:
query_params["FilterExpression"] = add_expressions(filters)
return query_params
def add_expressions(self, filters: dict):
if filters:
conditions = []
for key, value in filters.items():
if isinstance(value, str):
conditions.append(Attr(key).eq(value))
if isinstance(value, list):
conditions.append(Attr(key).is_in([v for v in value]))
return reduce(and_, conditions)
Run Code Online (Sandbox Code Playgroud)
使用上述每个答案中的部分,这是我能够使其工作的紧凑方式:
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()])))
Run Code Online (Sandbox Code Playgroud)
允许过滤多个条件filters作为dict. 例如:
{
'Status': 'Approved',
'SubmittedBy': 'JackCasey'
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
10884 次 |
| 最近记录: |