【问题标题】:ndb retrieving entity key by ID without parentndb 按 ID 检索实体键,没有父级
【发布时间】:2012-10-18 12:39:14
【问题描述】:

我想获得一个知道实体 ID 和祖先的实体密钥。 ID 在由祖先定义的实体组中是唯一的。 在我看来,使用 ndb 接口是不可能的。据我了解数据存储,这可能是由于此操作需要执行完整索引扫描这一事实引起的。 我使用的解决方法是在模型中创建一个计算属性,该属性将包含键的 id 部分。我现在可以进行祖先查询并获取密钥

class SomeModel(ndb.Model):
    ID = ndb.ComputedProperty( lambda self: self.key.id() )

    @classmethod
    def id_to_key(cls, identifier, ancestor):
        return cls.query(cls.ID == identifier,
                         ancestor = ancestor.key ).get( keys_only = True)

似乎可行,但是有没有更好的解决方案来解决这个问题?

更新 似乎对于数据存储,自然的解决方案是使用完整路径而不是标识符。一开始我觉得会很累。在阅读了 Dragonx 的答案后,我重新设计了我的应用程序。令我惊讶的是,现在一切看起来都简单多了。额外的好处是我的实体将使用更少的空间,并且我不需要额外的索引。

【问题讨论】:

  • 听起来你得到了正确的答案!
  • ID 保证在实体组中唯一 - 仅适用于给定的父实体。

标签: google-app-engine app-engine-ndb


【解决方案1】:

我也遇到了这个问题。我认为您确实有解决方案。

更好的解决方案是停止使用 ID 来引用实体,并存储实际密钥或完整路径。

在内部,我使用密钥而不是 ID。

在我的 rest API 上,我曾经使用http://url/kind/id(其中 id 看起来像“123”)来获取实体。我对其进行了修改以提供实体的完整祖先路径:http://url/kind/ancestor-ancestor-id (789-456-123),然后我会解析该字符串,生成一个密钥,然后通过密钥获取。

【讨论】:

  • 你是对的。使用完整的祖先路径,一切都变得更容易。似乎这是在数据存储中执行此类操作的正确方法。谢谢
  • 不要忘记数据存储中有一个“key”类型,可用于存储实际密钥 (KeyProperty)。
  • 附带说明,Java 有 these methods 来序列化和反序列化密钥
  • kurl = instance.key.urlsafe() -> instance = nb.Key(urlsafe=kurl) 我知道 urlsafe() 会生成一个丑陋的字符串,但它可以胜任
【解决方案2】:

既然你有关于你的祖先的完整信息并且你知道你的 id,你可以直接创建你的密钥并获取实体,如下所示:

my_key = ndb.Key(Ancestor, ancestor.key.id(), SomeModel, id)
entity = my_key.get()

通过这种方式,您可以避免查询比get 操作在金钱和速度方面的成本更高。

希望这会有所帮助。

【讨论】:

  • 如果祖先也是父母,这是一个很好的解决方案,但这不是我的情况
  • 既然你用了“祖先”这个词,我以为你的意思是它是一个父母。如果不是这种情况,那么我认为您的方法是正确的。
【解决方案3】:

我想对 dargonx 的回答做一点补充。

在我的前端应用程序中,我使用键的字符串表示:

str(instance.key())

当我需要对实例进行一些更改时,即使它是后代,我也只使用其键的字符串表示。例如我有key_str -- 来自请求删除实例的参数':

instance = Kind.get(key_str)
instance.delete()

【讨论】:

    【解决方案4】:

    我的解决方案是使用urlsafe 获取项目而不用担心父 ID:

    pk = ndb.Key(Product, 1234)
    usafe = LocationItem.get_by_id(5678, parent=pk).key.urlsafe()
    # now can get by urlsafe
    item = ndb.Key(urlsafe=usafe)
    print item
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-05-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-25
      相关资源
      最近更新 更多