Передача данных в нескольких версиях приложения - PullRequest
6 голосов
/ 06 октября 2011

При обновлении приложения GAE, каков наилучший способ обновить модель данных?

Номер версии приложения позволяет разделить несколько версий, но в этих версиях приложения используется одно и то же хранилище данных (согласно Как изменить приложение после развертывания в Google App Engine? ).Так что же происходит, когда я загружаю версию приложения с другой моделью данных (я думаю, Python здесь, но вопрос также должен быть действительным для Java)?Я думаю, это не должно быть проблемой, если изменения добавляют пустое поле и некоторые новые классы, поэтому существующая модель может быть расширена без вреда.Но что, если изменения в модели данных будут более глубокими?Действительно ли я теряю существующие данные, если они становятся несовместимыми с новой моделью данных?

Единственный вариант, который я вижу на данный момент, - это перевод хранилища данных в режим только для чтения, перевод данных в автономный режим и развертываниецелое снова.

1 Ответ

6 голосов
/ 06 октября 2011

Есть несколько способов справиться с этим, и они не являются взаимоисключающими:

  • Внесите неразрывные изменения в свое хранилище данных и обойдите возникающие проблемы. Вставка новых полей в существующие классы моделей, переключение полей с обязательных на необязательные, добавление новых моделей и т. Д. - это не нарушит совместимость с какими-либо существующими объектами. Но поскольку эти сущности не изменяются волшебным образом, чтобы соответствовать новой модели (помните, хранилище данных - это БД без схемы), вам может понадобиться устаревший код, который будет частично поддерживать старую модель. Например, если вы добавили новое поле, вам нужно будет получить к нему доступ через getattr(entity, "field_name", default_value), а не entity.field_name, чтобы оно не привело к AttributeError для старых объектов.
  • Постепенно преобразуйте объекты в новый формат. Это довольно просто: если вы найдете сущность, которая все еще использует старую модель, внесите соответствующие изменения. В приведенном выше примере вы захотите вернуть сущность с добавлением нового поля:

    if not hasattr(entity, "field_name"):
        entity.field_name = default_value
        entity.put()
    val = entity.field_name # no getattr'ing needed now
    

    В идеале все ваши объекты будут в конечном итоге обрабатываться таким образом, и вы сможете удалить код преобразования в какой-то момент. В действительности всегда будут некоторые остатки, которые следует преобразовать вручную - и это приведет нас к варианту номер три ...

  • Пакетное преобразование ваших сущностей в новый формат. Сложность логистики за этим сильно зависит от количества объектов для обработки, активности вашего сайта, ресурсов, которые вы можете посвятить процессу и т. Д. Просто отметьте, что использование простого MapReduce может быть не лучшей идеей - особенно если вы использовали постепенное преобразование Техника, описанная выше. Это связано с тем, что MapReduce обрабатывает все сущностей заданного вида (выбирая их), в то время как это может потребоваться лишь небольшому проценту. Следовательно, может быть полезным кодировать код преобразования вручную, явно писать запрос для старых объектов и, например, используя библиотеку, такую ​​как ndb .
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...