App Engine: Structured Property vs One-to-Many Link

My experience with creating data warehouses comes from Core Data on iOS, which supports one-to-many properties with another object.

I am working on an App Engine project that currently has three types of entities:

  • User , which represents the person using the application.
  • Project , which is a project. A User can be associated with many projects.
  • Post , which is the main content. A Project can have many posts.

User currently has a projects property, which is a one-to-many relationship to Project objects. Project has the posts property, that is, a one-to-many relationship with Post objects.

In this case, is it better to use a reference data warehouse property or a structured NDB property to work (and how are the two conceptually different from each other)? Is there a better way to structure my data?

+8
python database google-app-engine database-design
source share
2 answers

By reference, you probably mean the key property. This is a link to another data warehouse object. It is present in the db and ndb APIs. Using them, you can simulate a many-to-one relationship by pointing many objects to the key of another object.

A structured property is a completely different beast. It allows you to define a data structure and then include it in another object.

Here is an example from the documents in which you specify several addresses for one contact:

 class Address(ndb.Model): type = ndb.StringProperty() # Eg, '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() 

For your specific application, I would recommend using NDB (it is always better to use the latest version of api) with the following:

The publishing model included in the Project model as a repeating structured property. Users include a repeating KeyProperty, which contains the keys of projects for which they have permissions.

To make it a little more complex, you can create another model to represent projects and permissions / roles, and then include this as a repeating structured property in the user model.

The main reason you want to hang on the keys is to make data available in the light of possible HRD consistency.

Let me know if you need more help.

EDIT:

To clarify, a structure is suggested here:

Models:

  • User
  • User-Project-Mapping (optional, required to handle permissions)
  • Project
  • Message

The user model should contain User-Project-Mapping as a repeating structured property.

The project model should contain Post as a repeating structured property.

To map user projects, you only need to provide a link to the project and the corresponding representation of permissions.

Since this sounds like a commercial project, if you need more help, I will be happy to advise you. Hope you have enough to succeed!

+10
source share

There is one more point that was not mentioned and may matter: the objects inserted into StructuredProperty "are not fully functional objects", as indicated in this part of the documents . Below is the full quote (this applies to the same example mentioned in @Sologoub's answer):

Although address instances are defined using the same syntax as for model classes, they are not fully functional objects. They do not have their own keys in the data warehouse. They cannot be restored regardless of the contact object to which they belong.

This can lead to some design restrictions, given that you cannot reuse an entity property without duplicating data. KeyProperty , on the other hand, refers to another entity key and therefore represents entity relationships in a more "relational" way. And KeyProperties can also be repeated: just enable the repeated=True parameter.

+3
source share

All Articles