Reputation: 631
I'm thinking about making all my models inherit from the db.Expando class in order to support a loose denormalization protocol whereby selected attributes of models referenced by db.ReferenceProperty would be set on the owning class also.
class ImgModel(db.Expando):
height = db.IntegerProperty()
width = db.IntegerProperty()
url = db.StringProperty()
img_data = db.BlobReferenceProperty()
class company(db.Expando):
logo = db.DenormalizedImgProp(prefix=u'logo')
class DenormalizedImgProp(db.ReferenceProperty):
denorm_attrs = [u'height', u'width', u'url']
def __init__(self,prefix,verbose_name,collection_name,**attrs):
super(DenormalizedImgProp, self).__init__(ImgModel,verbose_name,collection_name,**attrs)
self.denorm_field_prefix = prefix
def __set__(self, model_instance, value):
super(DenormalizedImgProp, self).__set__(model_instance, value)
for attr in self.denorm_attrs:
setattr(model_instance, u'%s_%s' %
(self.denorm_field_prefix, attr),value)
Are there any performance drawbacks to having all models inherit from the Expando class? I understand more checks would be necessary to account for some idiosyncrasies, but I'm really just interested in whether this is fundamentally acceptable.
Upvotes: 0
Views: 333
Reputation: 326
To answer the title, most of the drawbacks of using dynamic properties are just about losing the benefits of property definitions: having to test for existence of some_attribute on object, not being able to query for entities with some_attribute unset, missing results from queries where the value on the entity has a different type from the value in the query, needing a lot more effort in validation and checking what kind of thing you are pulling out of datastore...
The datastore doesn't care whether you give it property type information or not, so at that level I don't think there are any real performance implications.
I am assuming the code will ultimately work as expected and there won't be any issue with writing both the ImgModel and the company, etc.
The concern this leaves me is that you will need to be careful about indexes. Expando makes it easier to create lots of dynamic properties without thinking about the impact on your indexes. The more indexes, the more time to write objects when property values change. The more queries requiring sorting or inequality filtering on multiple properties with multiple values, the easier it is to get huge custom indexes. Since you are automating the creation of these dynamic properties, you are going to have to make sure that little code changes don't blow up your indexes.
I think this is a difficult question to answer purely out of theory. Performance is going to be strongly dependent on what you actually do, little implementation details, and how those factors interact with the platform. For better and worse, code written against the local app server can sometimes do surprising things in production. So ultimately if this is something you really want to do, I think you should deploy and benchmark this against a simpler approach and judge for yourself whether it is "good enough."
Upvotes: 5