将多个键值匹配到TinyDB中的数据库条目?

时间:2018-04-05 17:22:35

标签: python tinydb

我很难发现是否可以使用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. 您能列出这些信息的链接吗?如果它存在,我很难找到这些信息。

  3. 这是我与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'}
    

2 个答案:

答案 0 :(得分:3)

您可以使用python builtin all来实现与示例代码更短,更灵活的工作:

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")

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

  

&#34;如果有这个姓氏的人存在,而第一个人就是这个人   名称存在,并且存在具有此中间名称的人,无论如何   他们是否都是同一个人,请返回具有匹配名字的人。&#34;

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

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

您的上述功能将返回查询内容

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

尽管某些人的中间名是&#34;随机&#34;不是&#34;其他&#34;,只是因为系统的其他人存在,其中间名是&#34;其他&#34;

您可能希望利用查询被覆盖的__and__ operator来查找包含您要查询的所有姓名的单个人:

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")

答案 1 :(得分:2)

根据Advanced Usage — TinyDB 3.8.1.post1 documentation,逻辑AND看起来像这样:

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

根据git blame of tinydb/queries.py,自第一次发布以来,它始终可用。