【问题标题】:GAE python ndb - How to get_by_id with projection?GAE python ndb - 如何使用投影获取_by_id?
【发布时间】:2014-09-08 02:33:12
【问题描述】:

我想这样做。

Content.get_by_id(content_id, projection=['title'])

但是,我遇到了一个错误。

TypeError: Unknown configuration option ('projection')

我应该这样做。怎么样?

Content.query(key=Key('Content', content_id)).get(projection=['title'])

为什么要通过投影来获取实体?因为Content.body 可能很大,所以我想减少数据库读取时间和实例时间。

【问题讨论】:

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


    【解决方案1】:

    如果您使用的是 ndb,下面的查询应该可以工作

    Content.query(key=Key('Content', content_id)).get(projection=[Content.title])
    

    注意:它从查询索引中获取此数据。因此,请确保为列启用了索引。参考https://developers.google.com/appengine/docs/python/ndb/queries#projection

    【讨论】:

    • 它不起作用。我得到了TypeError: __init__() got an unexpected keyword argument 'key'
    【解决方案2】:

    我想出了下面的代码。

    Content.query(Content.key == ndb.Key('Content', content_id)).get(projection=['etag'])
    

    我从https://developers.google.com/appengine/docs/python/ndb/properties找到了一个提示

    不要将属性命名为“键”。这个名字是为特殊的 用于存储模型密钥的属性。虽然它可能在本地工作,但 名为“key”的属性将阻止部署到 App Engine。

    【讨论】:

      【解决方案3】:

      有一个比当前发布的答案更简单的方法。

      正如之前的答案所提到的,预测仅适用于 ndb.Queries。

      之前的回答建议使用get_by_id返回的实体进行投影查询,形式如下:

      <Model>.query(<Model>.key == ndb.Key('<Model>', model_id).get(projection=['property_1', 'property_2', ...])
      

      但是,您可以直接操作模型的_properties。 (见:https://cloud.google.com/appengine/docs/standard/python/ndb/modelclass#intro_properties

      例如:

      desired_properties = ['title', 'tags']
      
      content = Content.get_by_id(content_id)
      content._properties = {k: v for k, v in content._properties.iteritems()
                             if k in desired_properties}
      print content
      

      这将更新实体属性并仅返回键在desired_properties 列表中的那些属性。

      不确定这是否是 _properties 背后的预期功能,但它可以工作,而且它还避免了为投影查询生成/维护额外索引的需要。

      唯一的缺点是这首先检索内存中的整个实体。如果实体具有会影响性能的任意大的元数据属性,则最好使用投影查询。

      【讨论】:

        【解决方案4】:

        投影仅用于查询,不能通过 id 获取。您可以将 content.body 放在不同的 db 模型中,并仅将其 ndb.Key 存储在 Content 中。

        【讨论】:

        • 感谢您的回答。我会记得作为一个选项。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-05-06
        • 2012-08-21
        • 1970-01-01
        • 1970-01-01
        • 2017-01-02
        • 1970-01-01
        相关资源
        最近更新 更多