Quali sono le applicazioni per Google App Engine Expando Class? E quali sono le buone pratiche ad esso correlate?Quando la classe Expando deve essere utilizzata nelle app di Google App Engine?
risposta
Due usi comuni di Expandos sono schemi parzialmente fissi e proprietà precedenti deleting.
Uso spesso Expando quando ho un tipo che richiede proprietà leggermente diverse tra le entità; in altre parole, quando ho bisogno di uno schema dinamico "parzialmente". Un caso d'uso è un'applicazione che prende gli ordini in cui alcuni prodotti sono liquidi (pensa acqua), alcuni sono unità fisiche (pensi DVD), e alcuni sono "altro" (pensa la farina). Alcuni campi, come codice articolo, prezzo e quantità, sono sempre necessari. Ma, cosa succede se sono necessari anche i dettagli di come è stata calcolata la quantità?
In genere una soluzione a schema fisso sarebbe quella di aggiungere una proprietà per tutte le variabili che potremmo usare: peso, quota, prima e dopo i pesi del nostro magazzino e così via. Questo fa schifo. Per ogni entità la maggior parte degli altri campi non sono necessari.
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()
Con Expando possiamo fare molto meglio. Potremmo usare lo unit_of_measure
per dirci come abbiamo calcolato la quantità. Le funzioni che calcolano la quantità possono impostare i campi dinamici e le funzioni che leggono le informazioni di quel metodo sanno cosa cercare. E l'entità non ha un mucchio di proprietà non necessarie.
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
Si potrebbe ottenere un risultato simile utilizzando una proprietà di testo o blob e la serializzazione di un dict di 'altri' valore ad essa. Expando fondamentalmente 'automatizza' quello per te.
Un'altra opzione nella situazione descritta consiste nell'utilizzare PolyModel, invece. –
È possibile; ma potresti finire per creare e importare tonnellate di modelli per gestire le variazioni (per questo tipo di esempio). Mi occupo di liquidi, e ci sono un * sacco * (la nostra app usa circa 12) di modi per calcolare il volume. –
Una delle più frequenti somme di ragioni per il modello Expando. Grazie! – Jon