7

我想获得一个知道实体 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 的答案后,我重新设计了我的应用程序。令我惊讶的是,现在一切看起来都简单多了。其他好处是我的实体将使用更少的空间,并且我不需要额外的索引。

4

4 回答 4

8

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

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

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

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

于 2012-10-18T15:02:34.740 回答
3

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

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

这样,您就可以避免get在金钱和速度方面进行比操作成本更高的查询。

希望这可以帮助。

于 2012-10-18T13:10:38.167 回答
1

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

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

str(instance.key())

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

instance = Kind.get(key_str)
instance.delete()
于 2013-04-11T07:17:53.650 回答
0

我的解决方案是使用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
于 2017-02-10T16:03:31.223 回答