zope.generations

Скриншот программы:
zope.generations
Детали программы:
Версия: 4.0.0 Alpha 1
Дата загрузки: 15 Apr 15
Разработчик: Zope Corporation and Contributors
Тип распространения: Бесплатная
Популярность: 2

Rating: nan/5 (Total Votes: 0)

zope.generations обеспечивает способ обновления объектов в базе данных, когда изменения схемы применения и NBSP;. схеме применения, по существу, структура данных, структура классов в случае ZODB или описаний таблиц в случае реляционная база данных.
Подробная документация
Поколения это способ обновления объектов в базе данных, когда изменения схемы приложения. Схеме применения, по существу, структура данных, структура классов в случае ZODB или описаний таблиц в случае реляционной базе данных.
При изменении структуры данных вашего приложения, например, изменить смысловое значение существующего поля в классе, вы будете иметь проблемы с базами данных, созданными перед изменением. Для более тщательного обсуждения и возможных решений см http://wiki.zope.org/zope3/DatabaseGenerations
Мы будем использовать компонентную архитектуру, и нам понадобится база данных и подключения:
& NBSP; >>> импорта CGI
& NBSP; >>> от импорта pprint pprint
& NBSP; >>> от zope.interface орудий импортных
& NBSP; >>> от импорта БД ZODB.tests.util
& NBSP; >>> дБ = DB ()
& NBSP; >>> подключений = db.open ()
& NBSP; >>> корень = conn.root ()
Представьте себе, что наша заявка оракул: вы можете научить его реагировать на фразы. Давайте держать его простым и хранить данные в Словаре:
& NBSP; >>> корень ['ответы'] = {'Привет': '? Привет & как вы это делаете ",
& NBSP; ... »? Смысл жизни": "42",
& NBSP; ... 'четыре & NBSP; >>> импортной сделки
& NBSP; >>> transaction.commit ()
Начальная настройка
Вот некоторые конкретные поколения-код. Мы создать и зарегистрировать SchemaManager. SchemaManagers отвечают за фактические обновлений базы данных. Он будет только фиктивный. Дело в том, чтобы сделать поколения модуль известно, что наше приложение поддерживает поколений.
Реализация по умолчанию SchemaManager не подходит для этого теста, потому что он использует модули Python для управления поколений. В настоящее время, это будет просто отлично, так как мы не хотим, чтобы сделать что-нибудь только пока.
& NBSP; >>> от импорта ISchemaManager zope.generations.interfaces
& NBSP; >>> от импорта SchemaManager zope.generations.generations
& NBSP; >>> импорта zope.component
& NBSP; >>> dummy_manager = SchemaManager (minimum_generation = 0, генерация = 0)
& NBSP; >>> zope.component.provideUtility (
& NBSP; ... dummy_manager, ISchemaManager, имя = 'some.app')
"some.app" является уникальным идентификатором. Вы должны использовать URI или пунктирную имя пакета.
Когда вы начинаете Zope и открыт база данных, IDatabaseOpenedWithRoot событие будет отправлено. Zope регистрирует evolveMinimumSubscriber по умолчанию в качестве обработчика этого события. Давайте моделировать это:
& NBSP; >>> класс DatabaseOpenedEventStub (объект):
& NBSP; ... Def __init __ (сам, базы данных):
& NBSP; ... self.database = базы данных
& NBSP; >>> событие = DatabaseOpenedEventStub (дБ)
& NBSP; >>> от импорта evolveMinimumSubscriber zope.generations.generations
& NBSP; >>> evolveMinimumSubscriber (событие)
Следствием этой акции в том, что в настоящее время база данных содержит тот факт, что наша нынешняя номер схемы 0. Когда мы обновляем схемы, Zope3 будете иметь представление о том, что отправной точкой было. Вот, видишь?
& NBSP; >>> от импорта generations_key zope.generations.generations
& NBSP; >>> корень [generations_key] ['some.app']
& NBSP; 0
В реальной жизни вы никогда не должны возиться с этим ключом сразу, но вы должны знать, что она существует.
Обновление сценарий
Вернуться к истории. Некоторое время проходит, и один из наших клиентов получает взломали, потому что мы забыли, чтобы избежать HTML специальные символы! Ужас! Мы должны решить эту проблему как можно скорее без потери данных. Мы решили использовать поколений, чтобы произвести впечатление наших сверстников.
Давайте обновить менеджер схемы (падение старый и установить новый обычай один):
& NBSP; >>> от импорта globalregistry zope.component
& NBSP; >>> GSM = globalregistry.getGlobalSiteManager ()
& NBSP; >>> gsm.unregisterUtility (при условии, = ISchemaManager, имя = 'some.app')
& NBSP; Правда
& NBSP; >>> класс MySchemaManager (объект):
& NBSP; ... орудия (ISchemaManager)
& NBSP; ...
& NBSP; ... minimum_generation = 1
& NBSP; ... поколение = 2
& NBSP; ...
& NBSP; ... Def развиваться (я, контекст, поколение):
& NBSP; ... корень = context.connection.root ()
и NBSP; ... Ответы = корень [''] ответы
& NBSP; ... если поколение == 1:
& NBSP; ... для вопроса, ответ на answers.items ():
& NBSP; ... Ответы [вопрос] = cgi.escape (ответ)
& NBSP; ... Элиф поколение == 2:
& NBSP; ... для вопроса, ответ на answers.items ():
& NBSP; ... дель ответы [вопрос]
& NBSP; ... Ответы [cgi.escape (вопрос)] = ответ
& NBSP; ... еще:
& NBSP; ... поднять ValueError ("облом")
& NBSP; ... корень ['ответы'] = Ответы настойчивость # пинг
& NBSP; ... transaction.commit ()
& NBSP; >>> менеджер = MySchemaManager ()
& NBSP; >>> zope.component.provideUtility (менеджер, ISchemaManager, имя = 'some.app')
Мы поставили minimum_generation 1. Это означает, что наше приложение не запустится с базой данных старше поколения 1. Атрибут поколения установлен на 2, что означает, что последнее поколение, что это SchemaManager знает о 2.
развиваться () является рабочей лошадкой здесь. Его работа, чтобы получить базу данных из поколения-1 в поколение. Он получает контекст, который имеет атрибут '' соединение, которое является подключение к ZODB. Вы можете использовать это, чтобы изменить объекты, как в этом примере.
В данном конкретном поколении реализации 1 избегает ответов (например, критические, потому что они могут быть введены любым!), Поколение 2 убегает вопросы (скажем, менее важные, потому что они могут быть введены уполномоченным Аренда персонала только).
В самом деле, вы действительно не нужно собственная реализация ISchemaManager. Одним из них является доступны, мы использовали его для манекена ранее. Он использует модули Python для организации функций Evolver. См свою строку документации для получения дополнительной информации.
В реальной жизни вы будете иметь гораздо более сложные структуры объектов, чем один здесь. Для того, чтобы ваша жизнь проще, есть две очень полезные функции, доступные в zope.generations.utility: findObjectsMatching () и findObjectsProviding (). Они будут копаться контейнеров рекурсивно, чтобы помочь вам искать старые объекты, которые вы хотите обновить, интерфейсом или некоторых других критериев. Они легко понять, проверить свои строки документации.
Поколения в действии
Итак, наша ярость клиент загружает наш последний код и перезапускает Zope. Мероприятие будет автоматически отправлено раз:
& NBSP; >>> событие = DatabaseOpenedEventStub (дБ)
& NBSP; >>> evolveMinimumSubscriber (событие)
Shazam! Клиент счастлив снова!
& NBSP; >>> pprint (корень ['ответы'])
& NBSP; {'Привет': 'Привет & как вы это делаете? ",
& NBSP; 'Смысл жизни?': '42',
& NBSP; 'четыре Потому evolveMinimumSubscriber очень ленивый, он только обновляет базу данных достаточно просто, так что ваше приложение может использовать его (в minimum_generation, что есть). Действительно, маркер, указывающий, что поколение базы данных был увеличен до 1:
& NBSP; >>> корень [generations_key] ['some.app']
& NBSP; 1
Мы видим, что поколения работают, поэтому мы решили сделать следующий шаг и развиваться в поколение 2. Давайте посмотрим, как это можно сделать вручную:
& NBSP; >>> от импорта zope.generations.generations развиваться
& NBSP; >>> развиваться (дБ)
& NBSP; >>> pprint (корень ['ответы'])
& NBSP; {'Привет': 'Привет & как вы это делаете? ",
& NBSP; 'Смысл жизни?': '42',
& NBSP; 'четыре & NBSP; >>> корень [generations_key] ['some.app']
& NBSP; 2
По умолчанию поведение развиваться модернизации к последнему поколению, предоставленной SchemaManager. Вы можете использовать Этот аргумент развиваться (), если вы хотите просто проверить, если вы хотите обновить или если вы хотите быть ленивым, как абоненту, который мы назвали ранее.
Заказ менеджеров схемы
Часто подсистем используются для создания приложения полагаются на другие подсистемы, чтобы работать правильно. Если обе подсистемы предоставить менеджерам схемы, часто бывает полезно знать порядок, в котором будет вызываться в эволюционируют. Это позволяет основу, и это клиенты, чтобы иметь возможность развиваться в концерте, и клиенты могут знать, что база будет эволюционировали до или после себя.
Это может быть достигнуто путем управления имена утилит менеджера схемы. Менеджеры схемы выполняются в порядке, определяемом сортировка их имена.
& NBSP; >>> Manager1 = SchemaManager (minimum_generation = 0, генерация = 0)
& NBSP; >>> manager2 = SchemaManager (minimum_generation = 0, генерация = 0)
& NBSP; >>> zope.component.provideUtility (
& NBSP; ... Manager1, ISchemaManager, имя = 'another.app')
& NBSP; >>> zope.component.provideUtility (
& NBSP; ... manager2, ISchemaManager, имя = 'another.app-расширение ")
Обратите внимание, как имя первого пакета используется для создания имен для зависимых пакетов. Это не является требованием рамках, но это удобный шаблон для такого использования.
Давайте развиваться базу данных, чтобы установить эти поколения:
& NBSP; >>> событие = DatabaseOpenedEventStub (дБ)
& NBSP; >>> evolveMinimumSubscriber (событие)
& NBSP; >>> корень [generations_key] ['another.app']
& NBSP; 0
& NBSP; >>> корень [generations_key] ['another.app-расширение "]
& NBSP; 0
Давайте предположим, что для какой-то причине каждая из этих подсистем нужно добавить поколение, и это поколение 1 "another.app-расширения" зависит от поколения 1 '' another.app. Нам нужно, чтобы обеспечить менеджеров схемы для каждого этой записи, что они были в ведении так что мы можем проверить результат:
& NBSP; >>> gsm.unregisterUtility (при условии, = ISchemaManager, имя = 'another.app')
& NBSP; Правда
& NBSP; >>> gsm.unregisterUtility (
& NBSP; ... при условии, = ISchemaManager, имя = 'another.app-расширение ")
& NBSP; Правда
& NBSP; >>> класс FoundationSchemaManager (объект):
& NBSP; ... орудия (ISchemaManager)
& NBSP; ...
& NBSP; ... minimum_generation = 1
& NBSP; ... поколение = 1
& NBSP; ...
& NBSP; ... Def развиваться (я, контекст, поколение):
& NBSP; ... корень = context.connection.root ()
& NBSP; ... упорядочение = root.get ("упорядочение", [])
& NBSP; ... если поколение == 1:
& NBSP; ... ordering.append ("основа 1 ')
& NBSP; ... поколение основа 1 »печать
& NBSP; ... еще:
& NBSP; ... поднять ValueError ("облом")
& NBSP; ... корень ['упорядочение'] = заказа # пинг настойчивость
& NBSP; ... transaction.commit ()
& NBSP; >>> класс DependentSchemaManager (объект):
& NBSP; ... орудия (ISchemaManager)
& NBSP; ...
& NBSP; ... minimum_generation = 1
& NBSP; ... поколение = 1
& NBSP; ...
& NBSP; ... Def развиваться (я, контекст, поколение):
& NBSP; ... корень = context.connection.root ()
& NBSP; ... упорядочение = root.get ("упорядочение", [])
& NBSP; ... если поколение == 1:
& NBSP; ... ordering.append ('зависит 1')
& NBSP; ... печать "зависит поколение 1"
& NBSP; ... еще:
& NBSP; ... поднять ValueError ("облом")
& NBSP; ... корень ['упорядочение'] = заказа # пинг настойчивость
& NBSP; ... transaction.commit ()
& NBSP; >>> Manager1 = FoundationSchemaManager ()
& NBSP; >>> manager2 = DependentSchemaManager ()
& NBSP; >>> zope.component.provideUtility (
& NBSP; ... Manager1, ISchemaManager, имя = 'another.app')
& NBSP; >>> zope.component.provideUtility (
& NBSP; ... manager2, ISchemaManager, имя = 'another.app-расширение ")
Развитие базы данных теперь всегда будет работать "another.app" Evolver до 'another.app-расширения "Evolver:
& NBSP; >>> событие = DatabaseOpenedEventStub (дБ)
& NBSP; >>> evolveMinimumSubscriber (событие)
& NBSP; поколение основа 1
& NBSP; зависеть поколение 1
& NBSP; >>> корень ['упорядочение']
& NBSP; ['основа' 1, 'зависит 1']
Установка
В приведенном выше примере, мы вручную инициализировать ответы. Мы не должны делать это вручную. Приложение должно быть в состоянии сделать это автоматически.
IInstallableSchemaManager распространяется ISchemaManager, обеспечивая установку способ выполнения intial установку приложения. Это лучшая альтернатива, чем регистрации абонентов в базе данных открыт.
Давайте определим новый менеджер схемы, которая включает установку:
& NBSP; >>> gsm.unregisterUtility (при условии, = ISchemaManager, имя = 'some.app')
& NBSP; Правда
& NBSP; >>> от импорта IInstallableSchemaManager zope.generations.interfaces
& NBSP; >>> класс MySchemaManager (объект):
& NBSP; ... орудия (IInstallableSchemaManager)
& NBSP; ...
& NBSP; ... minimum_generation = 1
& NBSP; ... поколение = 2
& NBSP; ...
& NBSP; ... Def установить (я, контекст):
& NBSP; ... корень = context.connection.root ()
& NBSP; ... корень ['ответы'] = {'Привет': '? Привет & как вы это делаете ",
& NBSP; ... »? Смысл жизни": "42",
& NBSP; ... 'четыре & NBSP; ... transaction.commit ()
& NBSP; ...
& NBSP; ... Def развиваться (я, контекст, поколение):
& NBSP; ... корень = context.connection.root ()
и NBSP; ... Ответы = корень [''] ответы
& NBSP; ... если поколение == 1:
& NBSP; ... для вопроса, ответ на answers.items ():
& NBSP; ... Ответы [вопрос] = cgi.escape (ответ)
& NBSP; ... Элиф поколение == 2:
& NBSP; ... для вопроса, ответ на answers.items ():
& NBSP; ... дель ответы [вопрос]
& NBSP; ... Ответы [cgi.escape (вопрос)] = ответ
& NBSP; ... еще:
& NBSP; ... поднять ValueError ("облом")
& NBSP; ... корень ['ответы'] = Ответы настойчивость # пинг
& NBSP; ... transaction.commit ()
& NBSP; >>> менеджер = MySchemaManager ()
& NBSP; >>> zope.component.provideUtility (менеджер, ISchemaManager, имя = 'some.app')
Теперь, давайте открыть новую базу данных:
& NBSP; >>> db.close ()
& NBSP; >>> дБ = DB ()
& NBSP; >>> подключений = db.open ()
& NBSP; '' ответы >>> в conn.root ()
& NBSP; Ложные
& NBSP; >>> событие = DatabaseOpenedEventStub (дБ)
& NBSP; >>> evolveMinimumSubscriber (событие)
& NBSP; >>> conn.sync ()
& NBSP; >>> корень = conn.root ()
& NBSP; >>> pprint (корень ['ответы'])
& NBSP; {'Привет': 'Привет & как вы это делаете? ",
& NBSP; 'Смысл жизни?': '42',
& NBSP; 'четыре & NBSP; >>> корень [generations_key] ['some.app']
& NBSP; 2
Журнал ZODB сделка отмечает, что наша установить скрипт был выполнен
& NBSP; >>> [. it.description для него в conn.db () storage.iterator ()] [- 2]
& NBSP; u'some.app: бег установить поколение "
(Минорной ноте: это не последняя запись, потому что есть две фиксации: MySchemaManager выполняет одну и evolveMinimumSubscriber выполняет второй MySchemaManager на самом деле не нужно совершать.).

Что нового В этом выпуске:.

  • Добавлена ​​поддержка Python 3.3
  • Заменены устаревшим использование zope.interface.implements с эквивалентным zope.interface.implementer декоратора.
  • Прекращена поддержка Python 2.4 и 2.5.

Что нового в версии 3.7.1:

  • Удалено Постройка часть, которая был использован во развития, но делает не компилируется на Windows.
  • скрипты поколение добавить примечание транзакций.

Требования

  • Python

Другие программы разработчика Zope Corporation and Contributors

zope.security
zope.security

12 May 15

cipher.configstore
cipher.configstore

20 Feb 15

five.customerize
five.customerize

20 Feb 15

Комментарии к zope.generations

Комментарии не найдены
добавить комментарий
Включите картинки!