Перенос(Миграция) данных

Содержание

Миграция данных это процесс сохранения корректных данных в БД после обновления модуля до новой версии. Например, простое переименование поля приведет к потере данных, если вы не имеете соответствующих скриптов переноса(миграции) данных.

Подготовка

Эти миграции происходят только в момент, когда меняется версия модуля в базе данных при его обновлении.

Детально описано здесь:

Этот класс управляет миграцией модулей. Файлы запускающие миграцию должны быть python файлами, содержащими функцию migrate(cr, installed_version). Эти файлы должны следовать определенному порядку расположения в древовидной структуре файлов: Каталог migrations, который содержит каталоги с версиями. Версия может быть module или server.module версией (в этом случае файлы будут обрабатываться только этой версией сервера). Имена python файлов могут начинаться с префиксов pre или post и будут выполняться, соответственно, до и после инициализации модуля. Скрипты с префиксом end запускаются после обновления всех модулей.

Example:

<moduledir>
`-- migrations
	|-- 1.0
	|   |-- pre-update_table_x.py
	|   |-- pre-update_table_y.py
	|   |-- post-create_plop_records.py
	|   |-- end-cleanup.py
	|   `-- README.txt                # не запускается
	|-- 16.0.1.1                      # запустится только на сервере версии 16.0
	|   |-- pre-delete_table_z.py
	|   `-- post-clean-data.py
	|-- 0.0.0
	|   `-- end-invariants.py         # запустится для всех версий при обновлении
	`-- foo.py                        # не запустится

Выполнение

Файлы миграции - это просто файлы с python кодом, которые не требуется где-либо регистрировать. При обновлении модуля Odoo осматривает каталог с именем migrations на наличие каталогов с промежуточной версией, вплоть до версии, для которой выполняется обновление. Это случается до того, как все остальные файлы были осмотрены, поэтому в этот момент в вашей БД ничего не поменялось. Затем, если каталоги с нужными именами версий были найдены Odoo запускает python файлы с префиксом pre в них. Они должны содержать и определять функцию с именем migrate Эта функция имеет два аргумента: курсор БД и текущая устанавливаемая версия

После успешной отработки всех функций с префиксом pre Odoo обновит модуль. Теперь текущее состояние БД отличается от предыдущего. Например, если в новой версии мы изменили тип поля, в БД эта колонка будет изменена без сохранения данных. Или, если было изменено имя поля, в новой версии будет создана только новая колонка.

Затем, после того, как модуль был обновлен, Odoo будет по тому же алгоритму искать скрипты с префиксом post и запускать их.

Скрипы с префиксом end будут запущены после обновления всех модулей.

Внимание: После отработки скриптов миграции откатить состояние БД назад будет невозможно, если какие либо ошибки возникнуть позже в процессе обновления модулей. Поэтому лучше сначала попытаться обновить модули без скриптов миграции на другой копии БД.

Пример

Для того, чтобы использовать следующий пример, вам необходимо переключить текущий разрабатываемый проект на другую ветку.

Сначала переключаемся на ветку - 16.0

Затем удалите текущую базу и создайте новую.

Убедитесь, что у вас не осталось вкладок со старыми сессиями

В этот моменты мы должны увидеть уже знакомую нам картину. Где версия модуля будет равна 16.0.1.0.0.

Версия модуля до миграции

  1. Откройте приложения Apps
  2. Введите в поисковой строке техническое имя нашего модуля first_module
  3. Переключите представление в Tree View

Теперь, не останавливая системы, откройте еще один терминал и переключитесь на ветку 16.0-migration-example

Переключение во втором терминале

После того как переключили ветку - выберите предыдущий терминал. Теперь, с помощью Ctrl-C остановите систему, нажмите вверх и перезапустите ее вы должны увидеть следующее:

Использование миграции

  1. В манифесте модуля мы изменили версию. Система запустит нашу миграцию только в случае, если новая версия модуля будет выше чем версия модуля сохраненная в БД
  2. Данной версии соответствует имя каталога в папке migrations внутри нашего модуля
  3. Функция, которая запустилась и изменила содержимое БД до применения обновлений самого модуля.
  4. В терминале мы можем увидеть отражение работы нашей функции и системы миграции

Результат миграции вы можете увидеть в нашем модуле:

Результат миграции

На первый взгляд у нас поменялось только имя колонки, но на самом деле это не так, если изучим исходный код, то увидим следующую картину:

Результат миграции

  1. Удалили поле field_one, а так же убрали заполнение полей в демо данных
  2. Добавили поле field_tree и в представлениях заменили поля с field_one на field_tree

Так, вот, если бы у нас не было миграции, где мы перед обновлением модуля удалили бы field_one и просто добавили field_tree, то все данные из поля были бы утеряны после обновления. Собственно для таких ситуаций класс миграций и создан

Задания для самостоятельного выполнения:

  1. Создайте новое поле field_four, добавьте его в представления
  2. Замените field_two на field_four
  3. Создайте миграцию для версии 16.0.1.0.3 на основании предыдущего примера

Обсуждение

Обсудить, указать на ошибки и опечатки можно здесь