查询python dict的库
dictquer的Python项目详细描述
dictquery
用于查询python dict的库
几个语法示例:
"age >= 12"
"`user.name` == 'cyberlis'"
"`user.email` MATCH /\w+@\w+\.com/ AND age != 11"
"`user.friends.age` > 12 AND `user.friends.name` LIKE 'Ra*ond'"
"email LIKE 'mariondelgado?bleendot?com'"
"eyeColor IN ['blue', 'green', 'black']"
"isActive AND (gender == 'female' OR age == 27)"
"latitude != longitude"
支持的数据类型
type | example |
---|---|
KEY | name, age, `friends.name.firstname`, `friends.age` |
NUMBER | 42, -12, 34.7 |
STRING | 'hello', "hellow" |
BOOLEAN | true, false |
NONE | none, null |
NOW | utc current datetime |
REGEXP | /\d+\d+\w+/ |
ARRAY | list of any items and any types |
按键
关键字文本必须以字母或下划线开头,例如:
_underscore
underscore_
变量名的其余部分可能由字母、数字和下划线组成。
password1
n00b
un_der_scores
如果您需要一个带有分隔符(.
或/
)的键,因为您使用嵌套键,或者在键中需要空格或其他标点符号,请使用反勾号(``)
dictquery支持由点.
或key_separator
参数中指定的任何分隔符拆分的嵌套dict。默认值key_separator='.'
>>> import dictquery as dq
>>> dq.match(data, "`friends.age` <= 26")
True
>>> compiled = dq.compile("`friends/age` <= 26", key_separator='/')
>>> compiled.match(data)
True
如果不需要嵌套键分析并希望按原样获取键,或者如果键包含分隔符char,则可以通过设置use_nested_keys=False
>>> import dictquery as dq
>>> dq.match(data, "`user.address`")
False
>>> dq.match(data, "age")
True
>>> compiled = dq.compile("`user.address`", use_nested_keys=False)
>>> compiled.match(data)
True
在查询中,可以按原样使用dict键,而无需任何二进制操作。dictquery将按键获取值并将其计算为bool
>>> import dictquery as dq
>>> dq.match(data, "isActive")
False
>>> dq.match(data, "isActive == false")
True
如果默认情况下找不到键,则此情况的计算结果为布尔值False
(未引发异常)。
如果找不到密钥,可以将raise_keyerror=True
设置为引发keyerror。
>>> import dictquery as dq
>>> dq.match(data, "favoriteFruit")
False
>>> compiled = dq.compile("`favoriteFruit`", raise_keyerror=True)
>>> compiled.match(data)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File ".../dictquery/dictquery/visitors.py", line 41, in match
return self.evaluate(data)
File ".../dictquery/dictquery/visitors.py", line 35, in evaluate
result = bool(self.ast.accept(self))
File ".../dictquery/dictquery/parsers.py", line 80, in accept
return visitor.visit_key(self)
File ".../dictquery/dictquery/visitors.py", line 84, in visit_key
values=self._get_dict_value(expr.value),
File ".../dictquery/dictquery/visitors.py", line 30, in _get_dict_value
self.key_separator, self.raise_keyerror)
File ".../dictquery/dictquery/datavalue.py", line 112, in query_value
raise DQKeyError("Key '{}' not found".format(data_key))
dictquery.exceptions.DQKeyError: "Key 'favoriteFruit' not found"
比较
Operation | Meaning |
---|---|
< | strictly less than |
<= | less than or equal |
> | strictly greater than |
>= | greater than or equal |
== | equal |
!= | not equal |
>>> import dictquery as dq
>>> dq.match(data, "age == 26")
True
>>> dq.match(data, "latitude > 12")
True
>>> dq.match(data, "longitude < 30")
True
>>> dq.match(data, "`friends.age` <= 26")
True
>>> dq.match(data, "longitude >= -130")
True
>>> dq.match(data, "id != 0")
True
>>> dq.match(data, "gender == 'male'")
False
字符串比较和匹配
字符串文字以多种方式编写:
- single quotes:'允许嵌入“双”引号'
- 双引号:“允许嵌入‘单’引号。”
Operation | Meaning |
---|---|
MATCH | regexp matching |
LIKE | glob like matching |
IN | dict item substring in string |
CONTAINS | dict item substring contains string |
<;,<;=,>;,>;=,=,!=与python处理字符串的方式相同
>>> import dictquery as dq
>>> dq.match(data, "eyeColor == 'green'")
True
>>> dq.match(data, "`name.firstname` != 'Ratliff'")
True
>>> dq.match(data, "eyeColor IN 'string with green color'")
True
>>> dq.match(data, "email CONTAINS '.com'")
True
>>> dq.match(data, r"email MATCH /\w+@\w+\.\w+/")
True
>>> dq.match(data, r"email LIKE 'mariondelgado@*'")
True
>>> dq.match(data, r"email LIKE 'mariondelgado?bleendot?com'")
True
默认情况下,所有与字符串相关的操作都区分大小写。要更改此行为,必须使用case_sensitive=False
>>> import dictquery as dq
>>> dq.match(data, "`name.firstname` == 'marion'")
False
>>> compiled = dq.compile("`name.firstname` == 'marion'", case_sensitive=False)
>>> compiled.match(data)
True
数组比较
Operation | Meaning |
---|---|
IN | dict item in array |
CONTAINS | dict item contains matching item |
>>> import dictquery as dq
>>> dq.match(data, "tags CONTAINS 'dolor'")
True
>>> dq.match(data, "eyeColor IN ['blue', 'green', 'black']")
True
dict中的键存在
CONTAINS
可与dict项一起使用,以检查是否键入dict
>>> import dictquery as dq
>>> dq.match(data, "name CONTAINS 'firstname'")
True
>>> dq.match(data, "name CONTAINS 'thirdname'")
False
日期时间与NOW
的比较
NOW
返回当前的UTC日期时间
使用标准操作(<;,<;=,>;,>;=,=,)可以将dict项与NOW
进行比较!=)
>>> import dictquery as dq
>>> dq.match(data, "registered < NOW")
True
>>> dq.match(data, "registered != NOW")
True
逻辑运算符
Operator | Meaning | Example |
---|---|---|
and | True if both the operands are true | x and y |
or | True if either of the operands is true | x or y |
not | True if operand is false (complements the operand) | not x |
>>> import dictquery as dq
>>> dq.match(data, "isActive AND gender == 'female'")
False
>>> dq.match(data, "isActive OR gender == 'female'")
True
>>> dq.match(data, "NOT isActive AND gender == 'female'")
True
您可以使用括号将语句分组或更改求值顺序
>>> import dictquery as dq
>>> dq.match(data, "isActive AND gender == 'female' OR age == 27")
True
>>> dq.match(data, "isActive AND (gender == 'female' OR age == 27)")
False
以上示例数据:
from datetime import datetime
data = {
"_id": 10,
"isActive": False,
"age": 27,
"eyeColor": "green",
"name": {
"firstname": "Marion",
"secondname": "Delgado",
},
"gender": "female",
"email": "mariondelgado@bleendot.com",
"registered": datetime.strptime("2015-03-29T06:07:58", "%Y-%m-%dT%H:%M:%S"),
"latitude": 74.785608,
"longitude": -112.366088,
"tags": [
"voluptate",
"ex",
"dolor",
"aute"
],
"user.address": "155 Village Road, Enetai, Puerto Rico, 2634",
"friends": [
{
"id": 0,
"name": {
"firstname": "Ratliff",
"secondname": "Becker",
},
"age": 27,
"eyeColor": "green"
},
{
"id": 1,
"name": {
"firstname": "Raymond",
"secondname": "Albert",
},
"age": 19,
"eyeColor": "brown"
},
{
"id": 2,
"name": {
"firstname": "Mavis",
"secondname": "Sheppard",
},
"age": 34,
"eyeColor": "blue"
}
]
}