我对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不接受连接,因此我们想要的“连接”必须使用类方法和属性进行模拟。使用上面的系统,我可以通过第一个中的唯一属性(在本例中为“name” - 很容易到达第二个数据库(Info)中的属性 - 假设没有两个具有相同名称的怪物)。
但是,如果我要打印一个包含100个怪物名称和相应地址的列表,第二个数据库(信息)将被点击100次。
问题:有没有更好的方法对此进行建模以提高性能?
答案 0 :(得分:1)
如果真的是一对一的关系,为什么要创建2个模型。鉴于你的例子,地址实体不能与任何怪物共享,所以为什么不把地址细节放在怪物中。
有些理由不这样做。
当您只需要一对夫妇时,地址可能变得很大,因此检索100个属性的效率会降低 - 尽管项目查询可能对此有所帮助。
你改变主意,想要看到所有生活在特兰西瓦尼亚的怪物 - 在这种情况下你会创建地址实体,而怪物将拥有指向地址的关键属性。当你弄清楚一些怪物可以生活在多个地方(狼人 - 伦敦,特兰西瓦尼亚,纽约;-)时,这显然会失败,在这种情况下,你要么在monstor中有一个重复的KeyProperty,要么是指向怪物的中间实体,地址。在你的情况下,我不认为怪物总体上有那么多记录的地址; - )
此外,如果您通过名称唯一识别怪物,则应考虑将名称存储为键的一部分。执行Monster.get_by_id(“dracula”)比按名称查询更快。
正如我在评论中写的那样(很差)。如果1.以上持有并且它是真正的一对一关系。然后,我会在创建地址时创建Address作为子实体(Monster是键中的父/祖先)。这允许你,
答案 1 :(得分:0)
我怀疑您可能通过使用以下链接中描述的元素来实现您的尝试 看看“多个键或实体上的操作”“Expando模型”“模型挂钩”
https://developers.google.com/appengine/docs/python/ndb/entities
(这可能更多是评论而非答案)