App Engine:结构化属性与参考属性,用于一对多关系

时间:2012-12-28 16:22:21

标签: python database google-app-engine database-design

我设计数据存储的背景来自iOS上的Core Data,它支持与另一个实体具有一对多关系的属性。

我正在开发一个目前有三种实体类型的App Engine项目:

  • User,代表使用该应用的人。
  • Project,代表一个项目。 User可能与许多项目相关联。
  • Post,这是Project背后的主要内容。 Project可能有很多帖子。

目前,User有一个属性projects,它与Project个实体的一对多关系。 Project有一个属性posts,它是与Post个实体的一对多关系。

在这种情况下,数据存储区的参考属性或NDB的结构化属性更适合作业(两者在概念上有何不同)?有没有更好的方法来构建我的数据?

2 个答案:

答案 0 :(得分:11)

通过引用属性,您可能意味着Key Property。这是对另一个数据存储区实体的引用。它存在于db和ndb API中。使用这些,您可以通过将许多实体指向另一个实体的键来建模多对一关系。

结构性属性是一种完全不同的野兽。它允许您定义数据结构,然后将其包含在另一个实体中。

以下是您为单个联系人提供多个地址的文档示例:

class Address(ndb.Model):
  type = ndb.StringProperty() # E.g., 'home', 'work'
  street = ndb.StringProperty()
  city = ndb.StringProperty()

class Contact(ndb.Model):
  name = ndb.StringProperty()
  addresses = ndb.StructuredProperty(Address, repeated=True)

guido = Contact(name='Guido',
                addresses=[Address(type='home',
                                   city='Amsterdam'),
                           Address(type='work',
                                   street='Spear St',
                                   city='SF')])

guido.put()

对于您的特定应用,我建议使用NDB(最好使用最新版本的api),具体如下:

将项目模型中包含的模型作为重复的结构化属性。 用户包括重复的KeyProperty,其中包含他们有权访问的项目的键。

为了使它更复杂,您可以创建另一个模型来表示项目和权限/角色,然后将其包含在用户模型中作为重复的结构化属性。

您希望坚持使用密钥的主要原因是根据HRD最终的一致性来保持数据的可访问性。

如果您需要更多帮助,请与我们联系。

编辑:

澄清一下,这是建议的结构:

型号:

  • 用户
  • 用户项目映射(可选,需要处理权限)
  • 项目

用户模型应包含User-Project-Mapping作为重复的结构化属性。

项目模型应包含Post作为重复的结构化属性。

User-Project-Mapping只需要包含对项目和相关权限表示的Key引用。

由于这听起来像是一个商业项目,如果你想进一步帮助我,我很乐意为你咨询。希望你有足够的成功!

答案 1 :(得分:3)

还有另一点没有提到并且可能是相关的:插入 StructuredProperty 中的实体不是完整的实体“,如this part of the docs中所述。以下是完整的引用(它指的是@Sologoub在答案中提到的相同示例):

  

尽管使用相同的地址实例定义了地址实例   语法和模型类一样,它们不是完整的实体。他们   在数据存储区中没有自己的密钥。他们无法检索   独立于它们所属的联系实体。

这可能会给设计带来一些限制,因为您不能在不重复数据的情况下重用实体的属性。另一方面, KeyProperty 引用另一个实体的密钥,因此以更“关系”的方式表示实体关系。 KeyProperties 也可以重复:只需添加repeated=True参数。