Reputation: 507
I'm looking for the best way of storing list of entities of different Kinds that have a common parent. I came up with the following:
class Action(ndb.Model):
date = ndb.DateTimeProperty(auto_now_add = True)
class ContentAction(Action):
content = ndb.StringProperty()
class AuthoredAction(Action):
author = ndb.StringProperty()
class ActionContainer(ndb.Model):
actions = ndb.StructuredProperty(Action, repeated=True, indexed=False)
Unfortunately once I add 2 entities of different types to the action list, there is no way to tell of which type the entity is (they all are Actions).
Also it appears that inherited properties of an entity that is of a different class than the entity that was added as a first one are lost. For instance, after adding a ContentAction and then AuthoredAction, the latter object is an Action with no 'author' property. Perhaps StructuredProperty allows only for storing objects of the same kind? Is there a better way of structuring this?
Upvotes: 0
Views: 533
Reputation: 16563
From the docs:
Reading back such [a structured] entity reconstructs the original Contact entity exactly. Although the Address instances are defined using the same syntax as for model classes, they are not full-fledged entities. They don't have their own keys in the Datastore. They cannot be retrieved independently of the Contact entity to which they belong.
So when you read the items in the actions
list, app engine creates an entity of type Action
from the data stored there. Thus, it makes sense why all they appear as kind Action
.
As an alternative to using a Polymodel
(which I don't like and avoid) would be to use regular Python classes or Python's namedtuple with ndb's Pickle Property
, like this:
ContentAction = namedtuple('ContentAction', ['date', 'content'])
AuthoredAction = namedtuple('AuthoredAction', ['date', 'author'])
class ActionContainer(ndb.Model):
actions = ndb.PickleProperty(repeated=True)
You can then put any namedtuple you like in the actions list.
If this doesn't work for you, then you can just use a KeyProperty as you indicate in your comment to the other answer.
Upvotes: 1
Reputation: 8393
I don't feel this is a very good storage strategy. If you're looking for inheritance of properties then what you're after is a PolyModel.
Some examples here: https://cloud.google.com/appengine/articles/polymodel?hl=en
Upvotes: 0