Defining attributes for objects/entities in python/google app engine
I've seen repeated examples like this:
from google.appengine.ext import db
import datetime
class Book(db.Expando):
pass
obj = Book()
obj.title = 'The Grapes of Wrath'
obj.author = 'John Steinbeck'
obj.copyright_year = 1939
obj.author_birthdate = datetime.date(1902, 2, 27)
obj.put()
It's the first time I've come across this sort of code, where the attributes are set outside of the class definition. It strikes me as a very bad practice. I prefer:
class Book(db.Model):
title = db.StringProperty()
author = db.StringProperty()
copyright_year = db.IntegerProperty()
author_birthdate = db.DateProperty()
...
obj = Book(title='The Grapes of Wrath', author='John Steinbeck', copyright_year=1939, author_birthdate=datetime.date(1902, 2, 27))
Can someone offer an assurance over the nature of the author's practice? Where and when such a method would be acceptable?
It was mentioned that google's model for data storag开发者_运维技巧e allows for unusual flexibility. I thought this example may be a poor and overly subtle introduction to that concept. The author has actually pointed out the disadvantages of this style, yet goes on to keep repeating it. So, there might be some advantage to it.
This is documented here. The snippet provided is valid, although it's not clear why the class is completely empty (might be for illustrational purposes). I suppose the main question is when to use Expando Model?
Imagine a site collecting orders for all kinds of goods possible. One customer might want to order a kitten, another one might want to order a book, etc. A books and a kitten have very little in common, maybe just a price and weight. But we want our customers to provide details on their irders, e.g. one customer might order a kitten 3 months old, siamese, blue eyed, and another might order "Lord of The Rings" 2nd edition, hardcover, author signed, etc. Although these properties aren't relevant at the moment of collecting an order, they are vital of your business logic. Also you might process these properties later.
The only solution here is to use Expando model, because you can't create a universal class (or hierarchy of classes) covering all the existing properties. The Expando model will hold all the general properties (price, weight, tracking id, shipping cost, custom fees, etc.) and methods (calculating total, discounts, etc.), the rest of the properties will be created by the customer dynamically at runtime. A model instance will be saved into the datastore with all its properties, and any particular instance will return all the properties defined on it via Model.properties() method.
That's funny. I read the same book and thought the same thing. I've been using App Engine Python since it launched and NEVER use Expando models.
I think the author's intent was to ease readers who may not be familiar with Python classes into the concept of defining models, but I didn't find it helpful.
One time that the datastore's flexibility came in handy for me was when I switched a field in one of my models from using DateTime to using a custom String property. Entities with fields of both types could live side-by-side, and I could migrate them as each was accessed.
精彩评论