如何在 App Engine 中表示一对一关系
假设您有一个“用户”记录的概念,您希望将其存储在数据存储中。
class User (db.Model):
first_name = db.StringProperty()
last_name = db.StringProperty()
created = db.DateTimeProperty(auto_now_add=True)
twitter_oauth_token = db.StringProperty()
twitter_oauth_secret = db.StringProperty()
有一些字段您几乎每次使用用户对象时都会使用,例如名字和姓氏。
然而,有些字段只有一个用例,例如 twitter_oauth_token 和 twitter_oauth_secret,当 95% 的时间都不需要它们时,对这些字段进行序列化和反序列化有点低效。
因此,如果您拆分模型:
class User (db.Model):
first_name = db.StringProperty()
last_name = db.StringProperty()
created = db.DateTimeProperty(auto_now_add=True)
class UserTwitterOauth(db.Model):
oauth_token = db.StringProperty(required=True)
oauth_secret = db.StringProperty(required=True)
created = db.DateTimeProperty(auto_now_add=True)
您可以将 ReferenceProperty 放入 UserTwitterOauth 中的用户,但这实际上是一对多,因为没有什么可以阻止每个用户有多个 UserTwitterOauth 对象。您希望最多有一个 UserTwitterOauth 与任何用户相关。如何将这些模型一对一关联起来?
Say you have a concept of "user" records that you'd like to store in the data store.
class User (db.Model):
first_name = db.StringProperty()
last_name = db.StringProperty()
created = db.DateTimeProperty(auto_now_add=True)
twitter_oauth_token = db.StringProperty()
twitter_oauth_secret = db.StringProperty()
There are some fields you'd like to use almost ever time you use a user object, like first_name and last_name.
However, there are some fields you only have one use case for, for example, twitter_oauth_token and twitter_oauth_secret, and it's somewhat inefficient to bother serializing and deserializing these when they're not needed 95% of the time.
So if you split your model up:
class User (db.Model):
first_name = db.StringProperty()
last_name = db.StringProperty()
created = db.DateTimeProperty(auto_now_add=True)
class UserTwitterOauth(db.Model):
oauth_token = db.StringProperty(required=True)
oauth_secret = db.StringProperty(required=True)
created = db.DateTimeProperty(auto_now_add=True)
You can put a ReferenceProperty to the User in the UserTwitterOauth, but this would actually be one-to-many as there's nothing stopping there to being multiple UserTwitterOauth objects per User. You want there to be at most one UserTwitterOauth related to any User. How can you relate these models on a one-to-one basis?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
在这种特定情况下,您最好的选择可能是使
UserTwitterOauth
实体成为具有众所周知的键名称的User
实体的子实体,如下所示:您可以添加
User
类的简单方法或属性,以便轻松检索附加信息,以及UserTwitterOauth
的类方法作为工厂方法,保留约定。顺便说一句,请注意
User
对于实体来说是一个危险的名称 - Users API 也有一个名为User
的类,除非您对导入非常小心,否则您可能会当您打算引用另一个时,最终会引用一个。In this specific case, your best option is probably to make the
UserTwitterOauth
entity a child of theUser
entity with a well-known key name, like so:You can add a straightforward method or property to the
User
class to make it easy to retrieve the additional information, and a class method toUserTwitterOauth
to serve as a factory method, preserving the convention.Incidentally, note that
User
is a dangerous name for an entity - the Users API has a class calledUser
too, and unless you're very careful with your imports, you may end up referring to one when you intend to refer to the other.在我看来,从 Twitter 访问令牌到用户的引用属性是迄今为止最容易维护的。确实,用户可以被许多访问令牌引用。
然而,在 GAE 工作时,您会发现自己很多时候都按照惯例做事。
编辑防止多个访问令牌引用同一用户:
您可以通过
User.usertwitteroauth_set
属性以查询方式访问引用访问令牌。如果您想要一个更具描述性的名称,请在设置 ReferenceProperty 时指定参数collection_name
。举例来说,您想在添加新访问令牌之前删除任何引用访问令牌,您可以按如下方式收集该逻辑:A reference property to the user from the twitter access token is by far the easiest to maintain, in my view. It is true that the user could be referenced by many access tokens.
You will however find yourself doing things by convention a lot of times when working GAE.
EDIT preventing several access tokens referencing same user:
You can access referencing access tokens as a query via the
User.usertwitteroauth_set
property. If you want a more descriptive name, specify the parametercollection_name
when setting up the ReferenceProperty. Say for example you want to remove any referencing access tokens before you add a new one, you could gather that logic as such: