6

我很难确定是否可以使用 TinyDB 一次检查多个键值。and目前我可以通过在这样的if语句中使用来检查多个字段:

def check_table(FNAME="NULL", LNAME="NULL", MNAME="NULL"):
    if (HHK_STAFF.search(Query().FNAME == FNAME)) != [] \
    and (HHK_STAFF.search(Query().MNAME == MNAME)) != [] \
    and (HHK_STAFF.search(Query().LNAME == LNAME)) != []:
        print(HHK_STAFF.search(Query().FNAME == FNAME)[0])
    else:
        print("user does not exist")

check_table(FNAME="Some", MNAME="Random", LNAME="Person")

它做我想要的,但是它接缝很笨重。我希望 TinyDB 中有内置的东西可以执行相同的功能而无需许多and语句。

我正在尝试做类似的事情:

HHK_STAFF.search(where(("FNAME", "MNAME", "LNAME")) == (FNAME, MNAME, LNAME)))

问题:

  1. 有没有人知道一种方法来查询()表的多个键值,而不是一次只有一个?

  2. 你能列出这个信息的链接吗?如果它存在的话,我很难找到这些信息。

这是我使用 TinyDB 的一个简单版本:

from tinydb import TinyDB, Query


#~~~~~~~~~~~~~~~~~~~~~~< CURRENT DBPATH >~~~~~~~~~~~~~~~~~~~~~~
DB = TinyDB('./DB_PATH/HHK_DB.json')
#~~~~~~~~~~~~~~~~~~~~~~< CURRENT TABLES >~~~~~~~~~~~~~~~~~~~~~~
HHK_STAFF = DB.table("HHK_STAFF")

HHK_STAFF.insert({'EMPLOYEE_ID':'00000001', 'FNAME': 'Some', 'LNAME':'Person', 'MNAME':'Random'})


def check_table(FNAME="NULL", LNAME="NULL", MNAME="NULL"):
    if (HHK_STAFF.search(Query().FNAME == FNAME)) != [] \
    and (HHK_STAFF.search(Query().MNAME == MNAME)) != [] \
    and (HHK_STAFF.search(Query().LNAME == LNAME)) != []:
        print(HHK_STAFF.search(Query().FNAME == FNAME)[0])
    else:
        print("user does not exist")

check_table(FNAME="Some", MNAME="Random", LNAME="Person")

结果:

{'EMPLOYEE_ID': '00000001', 'FNAME': 'Some', 'LNAME': 'Person', 'MNAME': 'Random'}
4

2 回答 2

4

根据Advanced Usage — TinyDB 3.8.1.post1 文档,逻辑 AND 如下所示:

q = Query()
HHK_STAFF.search((q.FNAME == FNAME) & (q.MNAME == MNAME) & (q.LNAME == LNAME))

根据git blameoftinydb/queries.py,它从第一个版本开始就一直可用。

于 2018-04-13T18:59:11.137 回答
4

您可以使用内置的 pythonall来实现更短、更灵活的工作,类似于您的示例代码:

def check_table2(**query):
    if all(HHK_STAFF.search(getattr(Query(), k) == v) 
           for k, v in query.items()):
        print(HHK_STAFF.search(Query().FNAME == query['FNAME'])[0])
    else:
        print("user does not exist")

但是您应该确定这实际上是您想要的。英语等价物是,

“如果存在这个姓氏的人,存在这个名字的人,并且存在这个中间名的人,无论他们是否都是同一个人,都返回与名字匹配的人。”

换句话说,如果我现在将另一个人添加到您的数据库中

HHK_STAFF.insert({'EMPLOYEE_ID':'00000002', 
                  'FNAME': 'Anne', 
                  'LNAME':'Person',
                  'MNAME':'Other'})

您上面的函数将为查询返回一些内容

check_table(FNAME="Some", MNAME="Other", LNAME="Person")

即使 Some 的中间名是“Random”而不是“Other”,只是因为系统上存在中间名是“Other”的其他人

相反,您可能希望利用 Query 的覆盖__and__运算符来查找具有您要查询的所有名称的单个人:

q = Query()
HHK_STAFF.search((q.FNAME=="Anne") & 
                 (q.MNAME=="Other") & 
                 (q.LNAME=="Person"))

或者,对于像我上面那样使用键值的东西,使用functools.reduce

from functools import reduce

def user_matching_all(**query):
    q = Query()
    out = HHK_STAFF.search(reduce(lambda x, y: x & y,
                                  [getattr(q, k) == v
                                   for k, v in query.items()]))
    if out:
        print(out)
    else:
        print("user does not exist")
于 2018-04-13T18:40:12.160 回答