Существует штраф за настройку всех возможных свойств, которые могут вам понадобиться с самого начала.
Если вы используете обычный db.Model, то каждое свойство будет сериализовано всякий раз, когда вы его помещаете (). Это включает накладные расходы на имя свойства, а также значение. Эти издержки присутствуют, даже если значение свойства не является обязательным и имеет значение None! (Хотя установка значения None, по-видимому, приводит к несколько меньшему представлению protobuf).
С другой стороны, если вы используете db.Expando и не задаете свойства, которые могут не отображаться, тогда только динамические свойства, которые фактически присутствуют в модели будет сериализовано. Динамические свойства, которых нет, вообще не сериализуются => нет накладных расходов. Однако, если вы явно объявите (фиксированные) свойства в модели, то у вас будут те же накладные расходы, что и у обычной модели db.Model (нет разницы в сериализации фиксированных свойств между обычными и расширяемыми моделями).
На практике я не знаю, хватит ли накладных расходов на использование фиксированных свойств, чтобы заметно повлиять на производительность, но это наверняка израсходует немного больше памяти и процессорного времени для сериализации даже пустых фиксированных полей.
На вашем месте я бы выбрал модель расширения и динамические свойства.
Пример приложения , который демонстрирует то, что я описал выше:
from google.appengine.ext import db, webapp
from google.appengine.ext.webapp.util import run_wsgi_app
# all model names equal length because they get serialized too
class EmptyModel(db.Model):
pass
class TestVModel(db.Model):
value = db.IntegerProperty(required=False)
class TestExpand(db.Expando):
pass
class MainPage(webapp.RequestHandler):
def get(self):
self.response.headers['Content-Type'] = 'text/plain'
# create an empty model, one with a prop = None, and one with a prop set
tEmpty = EmptyModel()
tNone = TestVModel()
tVal = TestVModel(value=5)
# do the same but using an expando model with a dynamic property
eEmpty = TestExpand()
eNone = TestExpand()
eNone.value = None
eVal = TestExpand()
eVal.value = 5
# determine the serialized size of each model (note: no keys assigned)
fEncodedSz = lambda o : len(db.model_to_protobuf(o).Encode())
szEmpty = fEncodedSz(tEmpty)
szNone = fEncodedSz(tNone)
szVal = fEncodedSz(tVal)
szEEmpty = fEncodedSz(eEmpty)
szENone = fEncodedSz(eNone)
szEVal = fEncodedSz(eVal)
# output the results
self.response.out.write("Comparison of model sizes with fixed props with expando models\nwith dynamic props:\n\n")
self.response.out.write("Model: empty=>%dB prop=None=>%dB prop=Val=>%dB\n" %\
(szEmpty, szNone, szVal))
self.response.out.write("Expando: empty=>%dB prop=None=>%dB prop=Val=>%dB\n\n" %\
(szEEmpty, szENone, szEVal))
self.response.out.write("Note that the expando property which specifies *no* value for the\ndynamic property 'value' is smaller than if 'None' is assigned.")
application = webapp.WSGIApplication([('/', MainPage)])
def main(): run_wsgi_app(application)
if __name__ == '__main__': main()
выход
Comparison of model sizes with fixed props with expando models
with dynamic props:
Model: empty=>30B prop=None=>43B prop=Val=>45B
Expando: empty=>30B prop=None=>43B prop=Val=>45B
Note that the expando property which specifies *no* value for the
dynamic property 'value' is smaller than if 'None' is assigned.