Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/314.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何基于条件动态构建查询?_Python_Google App Engine_App Engine Ndb - Fatal编程技术网

Python 如何基于条件动态构建查询?

Python 如何基于条件动态构建查询?,python,google-app-engine,app-engine-ndb,Python,Google App Engine,App Engine Ndb,我想根据一个用户请求,在可能的条件范围(0-4)上查询数据存储。NDB中的查询构建如下: query = Account.query(Account.userid >= 40, Account.userid < 50) query=Account.query(Account.userid>=40,Account.userid=': q=q.filter(getattr(ndb_类,prop)>=value) elif operation=='我最初认为,因为查询对象是不可变的,所以

我想根据一个用户请求,在可能的条件范围(0-4)上查询数据存储。NDB中的查询构建如下:

query = Account.query(Account.userid >= 40, Account.userid < 50)
query=Account.query(Account.userid>=40,Account.userid<50)
我有没有办法做一些类似的事情:

myfilter = []
myfilter.push('Account.userid >= 40')
myfilter.push('Account.userid < 50')
myfilter.push('Account.name == "John"')
query = Account.query(*myfilter)
myfilter=[]
myfilter.push('Account.userid>=40')
myfilter.push('Account.userid<50')
myfilter.push('Account.name=='John')
查询=帐户。查询(*myfilter)
根据条件,可能有0到4个筛选器参数。我的假设(可能是错误的)是,如果不需要,省略一个过滤器比使用一个catch all(例如Account.userid==*)更为理想

我知道您可以链接过滤器,但由于查询对象是不可变的,所以我不确定这是否有帮助

是的,这是可能的。发件人:

而不是在单个表达式中指定整个查询筛选器, 您可能会发现分步骤进行构建更为方便:例如:

query1 = Account.query()  # Retrieve all Account entitites
query2 = query1.filter(Account.userid >= 40)  # Filter on userid >= 40
query3 = query2.filter(Account.userid < 50)  # Filter on userid < 50 too

上面的代码片段特别利用了查询对象的可调性,对
query
变量的每个赋值实际上都存储了通过应用相应过滤器获得的新查询对象。通过相关的日志消息确认。

有一种更优雅的方法来实现这一点。顺便说一句,它更具活力:

def build_query_by(ndb_class, filters, sorts):
    """
    ndb_class: the ndb model class to query
    filters: a list of tuples of properties, operations and values
    sorts: a list of tuples of properties and order symbol
    """
    q = ndb_class.query()
    for prop, operation, value in filters:
        if operation == '==':
            q = q.filter(getattr(ndb_class, prop) == value)
        elif operation == '>=':
            q = q.filter(getattr(ndb_class, prop) >= value)
        elif operation == '<=':
            q = q.filter(getattr(ndb_class, prop) <= value)
        # more operations...

    for prop, symbol in sorts:
        if symbol == '-':
            q = q.order(-getattr(ndb_class, prop))
        else:
            q = q.order(getattr(ndb_class, prop))
    return q
def build_query_by(ndb_类、过滤器、排序):
"""
ndb_类:要查询的ndb模型类
筛选器:属性、操作和值的元组列表
排序:属性元组和顺序符号的列表
"""
q=ndb_类。查询()
对于过滤器中的道具、操作、值:
如果操作=='=':
q=q.filter(getattr(ndb_类,prop)=值)
elif操作=='>=':
q=q.filter(getattr(ndb_类,prop)>=value)

elif operation=='我最初认为,因为查询对象是不可变的,所以这不起作用。但我找到了一个办法让它发挥作用。它不是非常优雅,因为即使不使用过滤器,也必须为每个过滤器定义一个查询。(例如,即使您不关心特定的过滤器,也必须定义query2)。不管怎样,就我的目的而言,这已经足够好了。你说的“你不在乎那个特定的过滤器”是什么意思?如果参数是动态的,并且你使用的是不平等过滤器,那么你很可能会在@DanCornilescu处丢失索引?除非你能列举所有你认为可能的查询,并为每一个查询提供一个索引,否则我认为这种任意的查询并不适合datastore@jcjones1515当然,所有可能的最终查询的索引(即所有可能的条件组合和相应的过滤器)需要准备好/上菜。如果没有索引,查询将无法工作,不管它们是如何编写的(对我来说,问题主要是如何更好地编写查询)。@DanCornilescu谢谢。这与我最后所做的类似。小心,tho:不能在多个属性上使用不等式过滤器,不能在一个属性上使用不等式过滤器并在另一个属性上排序。请参阅此答案中引用的其他限制:在包含对代码的保护后,代码可能看起来不太整洁。
def build_query_by(ndb_class, filters, sorts):
    """
    ndb_class: the ndb model class to query
    filters: a list of tuples of properties, operations and values
    sorts: a list of tuples of properties and order symbol
    """
    q = ndb_class.query()
    for prop, operation, value in filters:
        if operation == '==':
            q = q.filter(getattr(ndb_class, prop) == value)
        elif operation == '>=':
            q = q.filter(getattr(ndb_class, prop) >= value)
        elif operation == '<=':
            q = q.filter(getattr(ndb_class, prop) <= value)
        # more operations...

    for prop, symbol in sorts:
        if symbol == '-':
            q = q.order(-getattr(ndb_class, prop))
        else:
            q = q.order(getattr(ndb_class, prop))
    return q