查询子项 table 并按父项字段在 NDB 中排序查询结果
Query on children table and order result of a query by parent's fields at NDB
在我的模型中,我有两个 table 如下相关:
from google.appengine.ext import ndb
class Parent(ndb.Model):
name = ndb.StringProperty()
class Child(ndb.Model):
parent = ndb.KeyProperty(kind=Parent, indexed=True)
name = ndb.StringProperty()
我想查询 Child
table 并按父名称(升序或降序)对子记录进行排序,
我如何使用 NDB ORM 执行此操作?
尽可能不希望借助Python在代码层面完成这个过程。
总的来说@gaefan 是正确的,你不能这样做。
我只能通过 3 种方法来完成这项工作。
parent 名称也必须是 parent 的密钥,然后您可以订购 Child.query().order(Child.parent).fetch()
。缺点是更改 parent 的名称实际上是不可能的。您必须在所有 Child 模型和其他具有外键的模型上更改它的键和所有外键
非规范化 parent 名称作为 Child 上的字段,如下所示:
classChild(ndb.Model):
parent = ndb.KeyProperty(种类=Parent, 索引=真)
名称 = ndb.StringProperty()
parent_name = ndb.StringProperty()
那么你可以Child.query().order(Child.parent_name).fetch()
。不利的一面是,如果您想更改 Parent.name,则必须更新所有 children。
- 如果这是像 http 处理程序之类的东西,你需要 return 一页有 10 个结果之类的东西,你可以先获取按名称排序的 10 parents,然后 运行 查询所有 children 拥有 parents
Child.query(namespace="test").filter(Child.parent.IN(order_parent_keys)).fetch()
之一的人(这是您在评论中建议的)。然后您必须在事后按 parent 名称订购 children。这种方法的问题是,它一次只适用于有限数量的 parent(我忘记了你可以传递多少个值给 .IN()
)。此外,当您 运行 超出 children 原始组 order_parent_keys
并且需要获取下一组时,分页也会变得很奇怪。
真正适合您的解决方案取决于您的数据。你有多少个 parent,你希望每个 parent 有多少个 children。此外,您尝试处理的数据量以及处理速度。
例如,如果您需要每天处理一次全部或大部分数据库,Google Dataflow 将是完美的选择。
在我的模型中,我有两个 table 如下相关:
from google.appengine.ext import ndb
class Parent(ndb.Model):
name = ndb.StringProperty()
class Child(ndb.Model):
parent = ndb.KeyProperty(kind=Parent, indexed=True)
name = ndb.StringProperty()
我想查询 Child
table 并按父名称(升序或降序)对子记录进行排序,
我如何使用 NDB ORM 执行此操作?
尽可能不希望借助Python在代码层面完成这个过程。
总的来说@gaefan 是正确的,你不能这样做。
我只能通过 3 种方法来完成这项工作。
parent 名称也必须是 parent 的密钥,然后您可以订购
Child.query().order(Child.parent).fetch()
。缺点是更改 parent 的名称实际上是不可能的。您必须在所有 Child 模型和其他具有外键的模型上更改它的键和所有外键非规范化 parent 名称作为 Child 上的字段,如下所示:
classChild(ndb.Model): parent = ndb.KeyProperty(种类=Parent, 索引=真) 名称 = ndb.StringProperty() parent_name = ndb.StringProperty()
那么你可以Child.query().order(Child.parent_name).fetch()
。不利的一面是,如果您想更改 Parent.name,则必须更新所有 children。
- 如果这是像 http 处理程序之类的东西,你需要 return 一页有 10 个结果之类的东西,你可以先获取按名称排序的 10 parents,然后 运行 查询所有 children 拥有 parents
Child.query(namespace="test").filter(Child.parent.IN(order_parent_keys)).fetch()
之一的人(这是您在评论中建议的)。然后您必须在事后按 parent 名称订购 children。这种方法的问题是,它一次只适用于有限数量的 parent(我忘记了你可以传递多少个值给.IN()
)。此外,当您 运行 超出 children 原始组order_parent_keys
并且需要获取下一组时,分页也会变得很奇怪。
真正适合您的解决方案取决于您的数据。你有多少个 parent,你希望每个 parent 有多少个 children。此外,您尝试处理的数据量以及处理速度。
例如,如果您需要每天处理一次全部或大部分数据库,Google Dataflow 将是完美的选择。