Перенос(Миграция) данных
Содержание
Миграция данных это процесс сохранения корректных данных в БД после обновления модуля до новой версии. Например, простое переименование поля приведет к потере данных, если вы не имеете соответствующих скриптов переноса(миграции) данных.
Подготовка
Эти миграции происходят только в момент, когда меняется версия модуля в базе данных при его обновлении.
Детально описано здесь:
Этот класс управляет миграцией модулей. Файлы запускающие миграцию должны быть 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
.
- Откройте приложения
Apps
- Введите в поисковой строке техническое имя нашего модуля
first_module
- Переключите представление в
Tree View
Теперь, не останавливая системы, откройте еще один терминал и переключитесь на ветку 16.0-migration-example
После того как переключили ветку - выберите предыдущий терминал. Теперь, с помощью Ctrl-C
остановите систему, нажмите вверх и перезапустите ее вы должны увидеть следующее:
- В манифесте модуля мы изменили версию. Система запустит нашу миграцию только в случае, если новая версия модуля будет выше чем версия модуля сохраненная в БД
- Данной версии соответствует имя каталога в папке
migrations
внутри нашего модуля - Функция, которая запустилась и изменила содержимое БД до применения обновлений самого модуля.
- В терминале мы можем увидеть отражение работы нашей функции и системы миграции
Результат миграции вы можете увидеть в нашем модуле:
На первый взгляд у нас поменялось только имя колонки, но на самом деле это не так, если изучим исходный код, то увидим следующую картину:
- Удалили поле
field_one
, а так же убрали заполнение полей в демо данных - Добавили поле
field_tree
и в представлениях заменили поля сfield_one
наfield_tree
Так, вот, если бы у нас не было миграции, где мы перед обновлением модуля удалили бы field_one
и просто добавили field_tree
, то все данные из поля были бы утеряны после обновления. Собственно для таких ситуаций класс миграций и создан
Задания для самостоятельного выполнения:
- Создайте новое поле
field_four
, добавьте его в представления - Замените
field_two
наfield_four
- Создайте миграцию для версии
16.0.1.0.3
на основании предыдущего примера
Обсуждение
Обсудить, указать на ошибки и опечатки можно здесь