在我们的应用程序中,我们经常有几个查询过滤器,用于检查存档状态,权限,实体层次结构等内容。这些过滤器是使用NDB的运算符重载构建的,例如: models.Item.isArchived == False
。我相信这些也被称为FilterNode
个实例。
给定一组这些FilterNode,如何将它们应用于在查询之外查找的单个实体?从Memcache说。
我的用例是我为端点设置了一组预定义的过滤器,该服务允许用户指定实体ID。我不是运行查询,而是通过ID获取。但我需要发布过滤器以确保它有效返回。
答案 0 :(得分:2)
使用Query对象找到了几种使用内存过滤的方法(这两种方法都假定NDB ...但可以修改为非)
这第一个只使用Python内置“filter()”...它不处理可能在查询中的排序顺序:
def filter_entities(query, entities):
#convert entities to list of protocol buffers
entity_pbs = [ent._to_pb() for ent in entities if ent is not None]
#assuming all entities are same type... just get type from first one
model_klass = type(entities[0])
#turn the query into a filter and hand it to builtin
filtered = filter(query.filters._to_filter(), entity_pbs)
#convert protocol buffers back into entities and hand back
return [klass._from_pb(ent) for ent in filtered if ent is not None]
另一种方法使用datastore_query中的apply_query ... 将考虑排序顺序:
from google.appengine.ext.ndb import tasklets
from google.appengine.datastore.datastore_query import apply_query
def apply_query(query, entities):
#convert list of entities to list of protocol buffers
entity_pbs = [ent._to_pb() for ent in entities if ent is not None]
#convert NDB query to datastore_query (needs connection)
conn = tasklets.get_context()._conn
dsquery = query._get_query(conn)
#call datastore_query.apply_query
filtered = apply_query(dsquery, [entity_pbs])
#convert protocol buffers back into entities and hand back
return [klass._from_pb(ent) for ent in filtered if ent is not None]
显然,我正在访问一些可能在将来发生变化的隐藏方法......所以请确保你已经编写了测试来捕捉这种可能性