我想根据用户请求在可能的标准范围(0-4)上查询数据存储区。 NDB中的查询构建如下:
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)
根据条件,可能有0到4个过滤器参数。我的假设(这可能是错误的)是省略过滤器比使用全能(例如,Account.userid == *)更为优化,如果不需要它。
我知道你可以链接过滤器,但由于查询对象是不可变的,所以不确定这对我有帮助。
答案 0 :(得分:2)
这样做有一种更优雅的方式。顺便说一下,更有活力:
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
答案 1 :(得分:1)
是的,有可能。来自Filtering by Property Values:
而不是在单个表达式中指定整个查询过滤器, 您可能会发现按步骤构建它更方便:例如:
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
query3
相当于之前的query
变量 例。注意查询对象是不可变的,所以构造query2
不会影响query1
和query3
的构建 不会影响query1
或query2
。
您可以使用此类增量查询构建技术根据需要有条件地添加过滤器。例如(假设可选条件之间的整体AND):
query = Account.query() # Retrieve all Account entitites
loggin.error(query)
if filter_by_userid:
query = query.filter(Account.userid >= 40, Account.userid < 50)
loggin.error(query)
if filter_by_username:
query = query.filter(Account.name == "John")
loggin.error(query)
loggin.error('Final: %s' % query)
上面的代码片段明确地利用了查询对象的不可变性,每个对query
变量的赋值实际存储了通过应用相应过滤器获得的 new 查询对象。由关联的日志消息确认。