Если бы мне пришлось выбирать, я бы выбрал вариант 1. Чтения как (если не больше) соответствуют другим параметрам. И все другие варианты имеют преимущества в скорости только при определенных обстоятельствах (небольшие или очень большие наборы изменений). Это также даст вам большую гибкость (с большей легкостью), например, историю очистки после x дней или историю запросов для разных типов моделей. Убедитесь, что вы создаете объекты истории как дочерние элементы измененного объекта в той же транзакции, чтобы гарантировать согласованность. Вы могли бы в конечном итоге с одним из них:
class HistoryEventFieldLevel(db.Model):
# parent, you don't have to define this
date = db.DateTime()
model = db.StringProperty()
property = db.StringProperty() # Name of changed property
action = db.EnumProperty(['insert', 'update', 'delete'])
old = db.PickleProperty() # Old value for field, empty on insert
new = db.PickleProperty() # New value for field, empty on delete
class HistoryEventModelLevel(db.Model):
# parent, you don't have to define this
date = db.DateTime()
model = db.StringProperty()
action = db.EnumProperty(['insert', 'update', 'delete'])
change = db.PickleProperty() # Dictionary with changed fields as keys and tuples (old value, new value) as values