0

我对 ndb 很陌生,但我已经明白我需要重新连接大脑中的某个区域来创建模型。我正在尝试创建一个简单的模型——只是为了理解如何设计一个 ndb 数据库——具有一对一的关系:例如,一个用户和他的信息。经过大量搜索 - 找到了文档,但很难找到不同的示例 - 并进行了一些实验(以几种不同的方式建模和查询),这是我找到的解决方案:

from google.appengine.ext import ndb

class Monster(ndb.Model):
    name = ndb.StringProperty()

    @classmethod
    def get_by_name(cls, name):
        return cls.query(cls.name == name).get()

    def get_info(self):
        return Info.query(Info.monster == self.key).get()

class Info(ndb.Model):
    monster = ndb.KeyProperty(kind='Monster')
    address = ndb.StringProperty()

a = Monster(name = "Dracula")
a.put()

b = Info(monster = a.key, address = "Transilvania")
b.put()

print Monster.get_by_name("Dracula").get_info().address

NDB 不接受连接,因此我们想要的“连接”必须使用类方法和属性来模拟。使用上述系统,我可以通过第一个数据库中的唯一属性(在本例中为“名称” - 假设没有两个同名的怪物)轻松访问第二个数据库(信息)中的属性。

但是,如果我想打印一个包含 100 个怪物名称和各自地址的列表,第二个数据库(信息)将被点击 100 次。

问题:有没有更好的方法对此进行建模以提高性能?

4

2 回答 2

1

如果它真的是一对一的关系,为什么要创建 2 个模型。鉴于您的示例,地址实体不能与任何怪物共享,所以为什么不将地址详细信息放入怪物中。

有一些你不这样做的原因。

  1. 当您只需要几个时,地址可能会变得很大,因此检索 100 个属性的效率会降低 - 尽管项目查询可能会有所帮助。

  2. 您改变主意并希望查看所有生活在特兰西瓦尼亚的怪物——在这种情况下,您将创建地址实体,而怪物将拥有指向该地址的关键属性。当您确定某些怪物可以生活在多个地方时,这显然会失败(狼人 - 伦敦,特兰西瓦尼亚,纽约;-),在这种情况下,您要么在怪物中有重复的 KeyProperty,要么有一个指向怪物的中间实体,并且地址。在您的情况下,我认为怪物总体上没有那么多记录在案的地址;-)

此外,如果您通过名称唯一标识怪物,则应考虑将名称存储为密钥的一部分。执行 Monster.get_by_id("dracula") 比按名称查询要快。

正如我在评论中写的(糟糕)。如果上述 1. 成立并且这是真正的一对一关系。然后,我会在创建地址时将地址创建为子实体(Monster 是键中的父/祖先)。这使您可以,

  1. 允许其他实体指向地址,
  2. 如果您创建了一堆子实体,请使用单个祖先查询获取它们)。3 如果你有怪物并且它再次拥有实体,那就是祖先查询。
  3. If you have a bunch of entities that should only exist if Monster instance exists and they are not children, then you have to do querys on all the entity types with KeyProperty's matching the key, and if theses entities are not PolyModels, then you have to perform a query for each entity type (and know you need to perform the query on a given entity, which involves a registry of some type, or hard coding things)
于 2013-04-20T11:35:30.827 回答
0

我怀疑您可能正在尝试的内容可以通过使用下面链接中描述的元素来实现查看“多个键或实体上的操作”“扩展模型”“模型挂钩”

https://developers.google.com/appengine/docs/python/ndb/entities

(这可能更像是评论而不是答案)

于 2013-04-20T14:51:48.860 回答