Миграции базы данных в 1С-Битрикс: быстро, правильно, надежно


- Поддерживаемые сущности
- Уникальные ID для миграции
- Конфигурирование модуля
- Команды модуля
- Проверка XML ID (команда validate)
- Автоматическое исправление ошибок XML ID (команда autofix)
- Экспорт в *.xml-файлы (команда export)
- Импорт из *.xml-файлов (команда import)
- Вывод логов предыдущей команды (команда log)
- Генерация демо-контента (команда для разработчиков generate)
- Тестирование модуля (команда для разработчиков unittest)
- Формат XML файлов
- Как пользоваться модулем
- Использование XML ID вместо ID в коде
- Выполнение примера из других модулей
- Вместо выводов
Если Вы разрабатываете проекты на 1С-Битрикс с привлечением двух и более программистов, то Вам сюда.Всё, всё, шо нажил непосильным трудом, всё же погибло!
Три магнитофона, три кинокамеры заграничных, три портсигара отечественных, куртка замшевая… Три. Куртки.
И они ещё борются за почётное звание «дома высокой культуры быта», а?..
ИНТЕРВОЛГА делится с сообществом веб-разработчиков своим крутым инструментом для АВТОМАТИЧЕСКОЙ миграции БД в 1С-Битрикс.
Как настоящие спортсмены, мы сделали три подхода к снаряду. Первый раз пробовали чужие решения. Второй раз — начинали свою разработку на скорую руку. Ну а получилось только на третий раз.
При использовании нашего модуля, время на выполнение релиза и перенос изменения БД, сокращается с нескольких часов до 10-20 минут (при отсутствии конфликтов).
Поддерживаемые сущности
Среди огромного разнообразия данных в 1С-Битрикс: Управление Сайтом для первого раза мы выбрали следующие сущности.
-
В модуле main:
-
Группы пользователей (сущность group)
-
Типы почтовых событий (сущность eventtype)
-
Почтовые события (сущность event)
-
Языки (сущность language)
-
Культура (сущность culture)
-
Сайты (сущность site)
-
Правила подключения шаблонов сайтов (сущность sitetemplate)
-
UF-поля (сущность field)
-
Варианты UF-списков (сущность fieldenum)
-
В модуле highloadblock:
-
ХЛБ (сущность highloadblock)
-
Поля ХЛБ (сущность field)
-
Варианты списков полей ХЛБ (сущность fieldenum)
-
В модуле catalog:
-
Типы цен (сущность pricetype)
-
В модуле sale:
-
Типы плательщиков (сущность persontype)
-
Группы свойств заказа (сущность propertygroup)
-
Свойства заказов (сущность property)
-
Варианты списков свойств заказов (сущность propertyvariant)
-
В модуле iblock:
-
Типы ИБ (сущность type)
-
ИБ (сущность iblock)
-
Свойства ИБ (сущность property)
-
Варианты свойств ИБ (сущность enum)
-
Поля разделов (сущность field)
-
Варианты полей разделов (сущность fieldenum)
-
Формы редактирования элементов и разделов ИБ (сущность form)
Уникальные ID для миграции
Для сопоставления записей между несколькими БД нужно выбрать уникальный ID. Родные числовые ID не подходят на эту роль — ими нельзя управлять и они могут различаться в разных БД.
Аналогичная проблема есть при обмене товарами и заказами между сайтом и 1С. Там она решается с помощью уникального внешнего кода — XML_ID. Вот только не у всех данных в БУС предусмотрено это поле. А у тех, что есть, оно не всегда уникальное. Пришлось нам сделать “надстройку” над системным полем XML ID. В таблице ниже описаны все сущности с их XML ID миграции.
Сущность | XML ID миграции |
---|---|
Группа пользователей | STRING_ID |
Тип почтового события | LID + EVENT_NAME |
Почтовый шаблон | md5(EMAIL_FROM+EMAIL_TO+EVENT_NAME+сайты) |
Язык | LID |
Культура | NAME |
Сайт | LID |
Настройка шаблона сайта | SITE_ID+TEMPLATE+md5(CONDITION) |
UF-поле | md5(ENTITY_ID+FIELD_NAME) |
Вариант списка UF-поля | XML_ID |
highload-блок | TABLE_NAME |
Поле highload-блока | md5(highload-блок+FIELD_NAME) |
Вариант списка поля highload-блока | XML_ID |
Тип цены | XML_ID |
Тип плательщика | md5(NAME+сайты) |
Группа свойств заказа | md5(NAME+Тип плательщика) |
Свойство заказа | md5(CODE+Тип плательщика) |
Вариант свойства заказа | md5(VALUE+Свойство заказа) |
Тип инфоблока | ID |
Инфоблок | XML_ID |
Свойство инфоблока | Инфоблок+XML_ID |
Вариант свойства инфоблока | Инфоблок+XML_ID |
Право на инфоблок | md5(Инфоблок+Группа) |
Форма редактирования | Инфоблок+несколько полей формы |
Поле раздела инфоблока | md5(Инфоблок+FIELD_NAME) |
Вариант списка поля раздела инфоблока | XML_ID |
Конфигурирование модуля
Конфигурацию можно изменить в файле /local/migrato/config.xml. Кстати, папку /local/migrato/ нужно обязательно добавить в репозиторий — помимо конфигурации здесь же будут и XML-файлы экспорта. Файл редактируется только вручную через FTP/SSH/файловый менеджер БУС. Синтаксис файла представлен в таблице:
Узел | Родительский узел | Описание |
---|---|---|
<config> | - | Корневой |
<module> | <config> | Настройки миграции модуля |
<name> | <module> | Название модуля |
<entity> | <module> | Сущность для миграции |
<name> | <entity> | Название сущности |
<options> | <config> | Мигрируемые настройки |
<exclude> | <options> | Регулярное выражение для исключения настроек из миграций |
Команды модуля
Для устранения проблем с таймаутом сервера (и чтобы придать тёплую ламповую атмосферу) вся работа с модулем после установки вынесена в командную строку. Точка входа: <папка модуля>/intervolga.migrato/tools/run.php (в примерах для краткости будет обозначена как run.php).
Интерфейс модуля в командной строке
Синтаксис простой:
$ php run.php команда [опции]
Доступные команды:
- validate (проверка XML ID)
- autofix (автоматическое исправление ошибок XML ID)
- export (экспорт данных из БД в XML)
- import (импорт данных из XML в БД)
- log (вывод логов последней запущенной команды)
Служебные команды (для разработчиков новых сущностей):
- generate (генерация демо-контента)
- unittest (тестирование модуля)
Доступные опции:
- -W или --win (изменить кодировку на win-1251)
- -U или --utf (изменить кодировку на UTF-8)
- -F или --fails (расширенный вывод ошибок после выполнения команды)
- -v (краткий отчёт по работе команды)
- -vv (подробный отчёт по работе команды)
Проверка XML ID (команда validate)
Модуль читает config.xml и проверяет, чтобы у всех экземпляров сущностей были заданы корректные XML ID. Команда ничего не изменяет в БД. Критерии корректного XML ID:
- Не пустой.
- Не целиком числовой.
- Попадает под регулярное выражение /^[a-z0-9\-_#.]+$/i (допустимы буквы латинского алфавита, цифры, тире, подчёркивание, решётка, точка).
- XML ID не должен повторяться в пределах сущности.
Автоматическое исправление ошибок XML ID (команда autofix)
Исправление ошибок XML ID — ответственный шаг, потому и вынесен в отдельную команду. Внимание: процесс может привести к модификации БД. Для всех найденных ошибок XML ID вызывается генератор XML_ID, создающий уникальный код сущности.
Экспорт в *.xml-файлы (команда export)
- Модуль записывает текущие настройки всех перечисленных модулей в файлы. Файлы складываются в /local/migrato/<название модуля>/option.xml.
- Модуль проверяет XML ID. Работа продолжается только если нет ошибок.
- Для каждой записи из перечисленных сущностей модуль создаёт файл: /local/migrato/<название модуля>/<название сущности>/data-<xml id>.xml
- Если данные были удалены — в соответствующем файле проставляется атрибут deleted=true в узле <data>
Импорт из *.xml-файлов (команда import)
- Модуль выполняет разбор и импорт настроек в БД.
- Модуль проводит проверку данных. Работа продолжается только если нет ошибок.
- Модуль читает data-файлы и импортирует записи.
- Модуль проверяет, остались ли сущности с неразрешёнными зависимостями. Если они есть — это ошибка.
- Модуль удаляет файлы, помеченные атрибутом deleted=true.
- Модуль проставляет ссылки в данных.
- Обновление поискового индекса, urlrewrite, сброс кэша // Вы ведь не забываете делать все это при релизах :) ?
Вывод логов предыдущей команды (команда log)
Если при выполнении одной из предыдущих команд произошла ошибка, увидеть их можно командой log. Использовав опцию --fails можно отфильтровать все записи, оставив только сообщения об ошибках. Если же вам удобнее работать с БД, то все ошибки сохраняются в таблице intervolga_migrato_log.
Генерация демо-контента (команда для разработчиков generate)
Помните, трава раньше была зеленее, мороженое вкуснее а модуль DEFA Tools был бесплатным? Его генератор демо-контента мы воспроизводить, конечно, не стали, но добавить по 2 записи в каждую сущности команда generate может. Команда полезна для разработчиков новых сущностей.
Тестирование модуля (команда для разработчиков unittest)
Вторая команда, полезная для разработчиков (и тестировщиков). Исполняется сценарий.
- export
- Файлы XML копируются в /local/migrato_old/
- import
- export
- diff папок /local/migrato/ и /local/migrato_old/
Если все сущности работают правильно, diff будет пустым. Если же нет — это значит, что в коде сущности есть ошибка и она импортируется в базу неправильно.
Формат XML файлов
Синтаксис XML-файлов миграции настроек модулей
Узел | Родительский узел | Описание |
---|---|---|
<options> | - | Родительский узел |
<option> | <options> | Настройка |
<name> | <option> | Название настройки |
<value> | <option> | Значение настройки |
<site> | <option> | Сайт, для которого задано значение |
Синтаксис XML-файлов миграции данных
Узел | Родительский узел | Описание |
---|---|---|
<data> | - | Родительский узел. Атрибут deleted говорит, что данные были удалены |
<xml_id> | <data> | XML ID данных |
<dependency> | <data> | Узел зависимости |
<reference> | <data> | Узел ссылки |
<field> | <data> | Узел простого поля |
<name> |
<dependency> <reference> <field> |
Название поля |
<value> |
<dependency> <reference> <field> |
Значение поля |
Как пользоваться модулем
Чтобы начать использовать модуль необходимо на боевом сайте создать оригинальный слепок БД:
- Установить модуль intervolga.migrato
- Настроить /local/migrato/config.xml
- validate
- autofix при необходимости или ручное исправление XML ID в БД
- export
- Добавить папку /local/migrato/ в git (он же у вас уже есть)
- git commit & git push
- Снять бекап с prod и развернуть на dev1, dev2 ...
Чтобы подготовить миграцию на песочнице devX после окончания работы над задачей:
- validate
- autofix при необходимости или ручное исправление XML ID в БД
- export
- git commit & git push
Выполнить миграцию (релиз) на боевом сайте:
- validate
- autofix при необходимости
- export (вдруг на бою были неучтённые в git’е изменения?)
- git commit при необходимости
- git pull
- разрешение конфликтов, если возникли
- git push, если возникли конфликты
- import
Использование XML ID вместо ID в коде
Пытливый читатель-программист может задать вопрос: как же теперь писать код, если использовать ID — плохо, а XML ID миграции не всегда совпадает с XML ID сущности?
Модуль предоставляет API для получения ID по XML ID:
\Intervolga\Migrato\Data\BaseData::getPublicId($xmlId)
Метод использует кеширование, так что о производительности не стоит беспокоиться.
Если вы используете константы для обращения к сущностям по ID, то вам только и нужно — сделать следующую замену.
Было
Стало
А вот второе изменение принять будет не так просто. Визуальный редактор БУСа при работе с компонентами генерирует код, в котором явно фигурируют “магические” неуникальные числовые ID.
Вот за такое хочется Битрикс от души поругать. Генерация кода зашита очень глубоко и кастомизировать её нет никакой возможности. Мы не стали придумывать хитрых способов подмены такого кода и просто ввели правило — визуальным редактором для редактирования компонентов не пользуемся. Программист один раз настраивает компонент, потом заменяет ID на XML ID миграции и никаких няш-мяш. Если знаете способ лучше — расскажите в комментариях, с радостью примем на вооружение.
Выполнение примера из других модулей
И, напоследок, выполнение общего примера нашим модулем. Сразу после установки проверили все записи на наличие внешних ключей и исправили ошибки:
Теперь можно создавать dev сайты для разработчиков - клонируем prod и обязательно делаем первый снимок базы данных (выполняем команду экспорт).
После того, как каждый программист выполнит свою задачу на своем сайте, он делает экспорт. Так как изменения были произведены только в ИБ модуле, то и экспортировать другие модули нет смысла (Настройка config файла).
После программист делает коммит экспортируемых файлов, и перед тем как вытолкнуть файлы на удаленный репозиторий необходимо проверить, может другой программист выполнил задание быстрее (git pull).
На этом шаге, возможна ситуация возникновения конфликта. Что же, тут есть 2 пути, смотря как Вам удобней работать. Если у вас git на серверах разработки, при конфликте появится такое предупреждение:
Открываете файл, например с помощью vim (vi local/migato/iblock/type/...) и выбираете, кто из программистов не врет.
После этого индексируете файлы и коммитете.
Есть еще второй путь, если у вас гит только на локальной машине, и синхронизируете все файлы с помощью гита, но на локальной машине. На примере показано возникновение конфликта в IDE PHPStorm.
Как только все конфликты разрешены, программист должен вытолкнуть изменения на сервер.
После того, как все программисты вытолкнули свои изменения, версия базы данных в системе управления версий стабилизируется. Это значит, что наступило время делать релиз. После которого, чтобы обновить любой сайт (будь то сайт для разработки или prod), достаточно трех глобальный вещей:
- Выполнить pull
- Проверить config файл (какие именно модули и сущности нам нужны)
- Выполнить импорт данных
В результате, каждый сайт имеет актуальную версию базы данных со всеми изменениями. Будь то удаление, создание или изменение записи с конфликтами или без, наш модуль превосходно справился с поставленными задачами.
Вместо выводов
Инструмент для миграции изменений БД жизненно необходим при ответственной командной работе над проектами. До сегодняшнего дня эта задача в мире 1С-Битрикс решалась очень плохо.
Мы же разработали промышленное решение этой задачи и отдаем его бесплатно всем желающим. Пользуйтесь, предлагайте улучшения, участвуйте в развитии, мы будем рады. Чтобы получить ссылку на установку модуля миграций для Битрикс, “поделитесь” статьей в соцсетях и укажите ссылку в форму под статьей. Ссылка на репозиторий с документацией придет вам на почту.