When Expando Class should be used in Google App Engine Apps?
What are the applications for Google App Engine Expando Class? And what are the good practices related to i开发者_如何学Pythont?
Two common uses of Expandos are partially-fixed schemas and deleting old properties.
I frequently use Expando when I have a kind that needs slightly different properties across entities; in other words, when I need a 'partially' dynamic schema. One use-cases is an application that takes orders where some products are liquid (think water), some are physical units (think DVDs), and some are 'other' (think flour). Some fields, like item code, price and quantity, are always needed. But, what if the details of how quantity was computed is also needed?
Typically a fixed-schema solution would be to add a property for all of the variables we might use: weight, dimension, before and after weights of our stock, and so on. That sucks. For every entity most of the other fields are not needed.
class Order(db.Model):
# These fields are always needed.
item_code = db.StringProperty()
unit_of_measure = db.StringProperty()
unit_price = db.FloatProperty()
quantity = db.FloatProperty()
# These fields are used depending on the unit of measure.
weight = db.FloatProperty()
volume = db.FloatProperty()
stock_start_weight = db.FloatProperty()
stock_end_weight = db.FloatProperty()
With Expando we can do much better. We could use the unit_of_measure
to tell us how we computed quantity. The functions that compute quantity can set the dynamic fields, and the functions that read that method's information know what to look for. And, the entity does not have a bunch of unneeded properties.
class Order(db.Expando):
# Every instance has these fields.
item_code = db.StringProperty()
unit_of_measure = db.StringProperty()
unit_price = db.FloatProperty()
quantity = db.FloatProperty()
def compute_gallons(entity, kilograms, kg_per_gallon):
# Set the fixed fields.
entity.unit_of_measure = 'GAL'
entity.quantity = kilograms / kg_per_gallon
# Set the gallon specific fields:
entity.weight = kilograms
entity.density = kg_per_gallon
You could achieve a similar result by using a text or blob property and serializing a dict of 'other' value to it. Expando basically 'automates' that for you.
精彩评论