Python:在数据存储中建模一对一关系
假设我们有两个模型:Python:在数据存储中建模一对一关系,python,google-app-engine,data-structures,google-cloud-datastore,Python,Google App Engine,Data Structures,Google Cloud Datastore,假设我们有两个模型:User和Token。一个用户可能只有一个令牌,而令牌只能属于一个用户 来自关系数据库,下面的方法似乎可以做到这一点: 这当然也会创建User.token\u set,这是一个db.Query。 但是我真的很想用,User.token而不是User.token\u set.get()来访问令牌,那么 class User(db.Model): name = db.StringProperty() token = db.ReferenceProperty(Tok
User
和Token
。一个用户可能只有一个令牌
,而令牌
只能属于一个用户
来自关系数据库,下面的方法似乎可以做到这一点:
这当然也会创建User.token\u set
,这是一个db.Query
。
但是我真的很想用,User.token
而不是User.token\u set.get()
来访问令牌,那么
class User(db.Model):
name = db.StringProperty()
token = db.ReferenceProperty(Token)
class Token(db.Model):
name = db.StringProperty()
owner = db.ReferenceProperty(User)
现在我可以以双向方式访问它们:User.token
&User.owner
。我已经自动创建了.token\u集
和用户集
这有什么问题吗?在逻辑方面,在性能方面
也许我不应该有两个模特。实际上,它们都包含四个或五个属性。他们应该是一个吗?什么时候一对一的关系应该被抛弃,只是合并成一个模型
谢谢你的任何意见 这是appengine数据存储。这不是sql。您应该将系统使用的数据分组在一起。假设您有用户和令牌一起使用的地方,并且由于多对一不存在任何问题,因此这些可以放在同一个模型实例中。这将为您提供更好的性能(例如,通过令牌更简单地检索用户)和更容易的一致性处理(更新令牌和用户将在单个事务中) 我不知道这里是否可以接受自链接,所以如果不能,也许有人会编辑这个,但我写这篇文章是为了收集我在数据存储方面的经验。你可能会发现它很有用
[编辑:思考这个问题的一种方式:你不是在建模数据。你在编写一个旨在扩展的系统。这——而不是建模数据——是驱动一切的因素。我不是说这是一个好主意,但appengine就是这么做的。如果你的主要任务是建模数据——例如,如果你想让多个应用程序使用你的以不同的方式获取数据-那么您不应该使用appengine。]将令牌引用添加到用户类有其优点和缺点。这样做的好处是,您将在令牌检索中获得更好的性能。缺点是,插入数据时,您将需要更多的事务
user = User(name='john').put()
token = Token(name='somehash', user=user).put()
user.token = token
user.put()
在删除令牌时,还必须处理空引用
如果语法糖是您想要的,也许您可以使用类装饰器:
class User(db.Model):
name = db.StringProperty()
@property
def token(self):
if not hasattr(self, '_token_cached'):
setattr(self, '_token_cached', self.token_set.get())
return self._token_cached
class User(db.Model):
name = db.StringProperty()
@property
def token(self):
if not hasattr(self, '_token_cached'):
setattr(self, '_token_cached', self.token_set.get())
return self._token_cached