【问题标题】:How to query ndb for all properties and include keyproperty values?如何查询 ndb 的所有属性并包含 keyproperty 值?
【发布时间】:2015-04-14 09:33:39
【问题描述】:

本周开始使用带有 Python 端点的 Google App Engine。 目标是查询实体并包含所有 keyproperty 值。 模型:

class Person(EndpointsModel):
  _message_fields_schema = ('id', 'surname', 'lastname', 'created')
  surname = ndb.StringProperty(indexed=False)
  lastname = ndb.StringProperty(indexed=False)

class Magazine(EndpointsModel):
  _message_fields_schema = ('id', 'name')
  name = ndb.StringProperty(indexed=False)

class Subscription(EndpointsModel):
  _message_fields_schema = ('id', 'publication', 'person', 'amount')
  magazine = ndb.KeyProperty(kind=Magazine)
  person = ndb.KeyProperty(kind=Person)
  amount = ndb.IntegerProperty()

通过以下方式查询这些模型以检索所有项目:

@endpoints.api(name='subscription', version='v1', description='REST API for Subscriptions')
 class SubscriptionV1(remote.Service):
   @Subscription.query_method(path='subscriptions', name='subscriptions.list')
   def SubscriptionList(self, query):
     return query

结果是:

{
 "items": [
  {
   "created": "2015-02-13T09:40:22.514000",
   "id": "6225984592281600",
   "modified": "2015-02-13T09:40:22.514000",
   "magazine": "ahNkZXZ-YXZpYW4tc2xpY2UtODUwchgLEgtQdWJsaWNhdGlvbhiAgICAgND7CQw",
   "synced": false
  }
 ]
}

虽然我希望它是:

"magazine": {"id": 123456789123456789,
"name": "Tech magazine"}

到处找,但找不到好的查询。 查询应该如何得到这个结果?

【问题讨论】:

  • 您能否确认您的查询旨在返回所有Subscription 实体?您是否尝试过使用response_fieldscollection_fields 装饰器参数,例如this example?我很想知道结果(我发现与 Java 相比,Python 中的 Cloud Endpoints 文档没有那么详细)。
  • 是的,目的是返回所有Subscription 实体。不,还没试过。我不知道进行查询的方法,因此它检索属于密钥的magazine。在 SQL 中我会使用内部连接,但在 NoSQL 中不知道
  • 我没有在 Python 中探索过 Cloud Endpoints,但我认为您可能需要考虑使用底层的 ProtoRPC API 来创建自己的自定义消息。也就是说,请记住,如果您对每个 Subscriptionmagazine 键执行单独的 Datastore get 操作,则效率不会很高。当然,ndb 将缓存实体,但缓存未命中将代价高昂。 Cloud Trace 将向您展示您的 subscriptions.list API 背后的 RPC。
  • 查询本身无法获取 Subscription 实体的 KeyProperty 所引用的杂志实体。您需要取消对自己的引用,.一种可能的策略是在 Subscription 属性中存储杂志名称的计算属性。此外,您需要自己构建结果集以满足您的要求。 (也许计算属性可以为你做到这一点)

标签: python google-app-engine google-cloud-datastore google-cloud-endpoints app-engine-ndb


【解决方案1】:

如果我正确阅读了您的代码,您将使用提供EndpointsAliasProperty 的端点原型数据存储。在您的示例中,您可以使用它来获得正确的订阅: 将杂志重命名为 magazine_key 并在您的模型中定义 EndpointsAliasProperty

@EndpointsAliasProperty(property_type=Subscription.ProtoModel())
def magazine(self):
    if self.magazine_key != None:
        magazine = self.magazine_key.get()
        return magazine

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-12
    相关资源
    最近更新 更多