ndb按ID检索实体密钥而没有父项

时间:2012-10-18 12:39:15

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

我想获得一个知道实体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 个答案:

答案 0 :(得分:8)

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

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

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

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

答案 1 :(得分:3)

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

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

这样,您就可以避免在金钱和速度方面进行超过get操作的查询。

希望这有帮助。

答案 2 :(得分:1)

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

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

str(instance.key())

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

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

答案 3 :(得分:0)

我的解决方案是使用dat2 <- reshape(data = dat, ids = rownames(dat), direction = 'long', varying = list(names(dat)), times = names(dat)) dat2 <- transform(dat2, grp = ave(id, id, FUN = function(i) rep(1:4, each = 25))) aggregate(X1 ~ id + grp, dat2, FUN = function(x) c(std = sd(x), mn = mean(x))) 获取项目,而无需担心父ID:

urlsafe