You need to be careful with some of your assumptions here. First of
all in you "Cascading relations" you use the parent property to
implement an ancestor relationship. While this if fine for the use
case you provide it would not be very efficient in the case where
there are a lot of children associated with a parent. This is because
this results in a very large entity group. The more entity groups your
application has--that is, the more root entities there are--the more
efficiently the datastore can distribute the entity groups across
datastore nodes. Thus for efficiency you should avoid the case where
there are a lot of children. According to the docs, "A good rule of
thumb for entity groups is that they should be about the size of a
single user's worth of data or smaller.".
Now to address to "Many-to-Many (m:n)" section. It might be a better
idea to implement a different entity to represent the relationship
between a human and the cars they own. Something like:
class CarOwner(db.Model):
car = db.Reference(Car, required=True)
owner = db.Reference(Human, required=True)
The reason for this is that you could add more fields to this which
may be beneficial later in a query. Lets say we add a bought field
that contains the date the car was bough. Then one could get cars
owned by Jack that he bought after a certain date.
Now you could have a static method on Car ...
@staticmethod
def get_owner_cars(human, bought):
"""Returns the cars that the given human owns since a bought
date."""
if not human: return []
carsowned = db.Query(CarOwner).filter('owner =',
human).filter('bought=', bought)
return [entry.car for entry in carsowned ]
A useful non-static method on Car may be ...
def human_owns(self, human):
"""Returns true if the given human owns this car."""
if not human: return False
query = db.Query(CarOwner)
query.filter('car =', self)
query.filter('owner =', human)
return query.get()