Миграции базы данных в 1С-Битрикс.png

Всё, всё, шо нажил непосильным трудом, всё же погибло!
Три магнитофона, три кинокамеры заграничных, три портсигара отечественных, куртка замшевая… Три. Куртки.
И они ещё борются за почётное звание «дома высокой культуры быта», а?..

(с) Иван Васильевич меняет профессию
Если Вы разрабатываете проекты на 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 команда [опции]

Доступные команды:
  1. validate (проверка XML ID);
  2. autofix (автоматическое исправление ошибок XML ID);
  3. export (экспорт данных из БД в XML);
  4. import (импорт данных из XML в БД);
  5. log (вывод логов последней запущенной команды).
Служебные команды (для разработчиков новых сущностей):
  1. generate (генерация демо-контента);
  2. 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)

  1. Модуль записывает текущие настройки всех перечисленных модулей в файлы. Файлы складываются в /local/migrato/<название модуля>/option.xml;
  2. Модуль проверяет XML ID. Работа продолжается только если нет ошибок;
  3. Для каждой записи из перечисленных сущностей модуль создаёт файл: /local/migrato/<название модуля>/<название сущности>/data-<xml id>.xml;
  4. Если данные были удалены — в соответствующем файле проставляется атрибут deleted=true в узле <data>.

Импорт из *.xml-файлов (команда import)

  1. Модуль выполняет разбор и импорт настроек в БД.
  2. Модуль проводит проверку данных. Работа продолжается только если нет ошибок.
  3. Модуль читает data-файлы и импортирует записи.
  4. Модуль проверяет, остались ли сущности с неразрешёнными зависимостями. Если они есть — это ошибка.
  5. Модуль удаляет файлы, помеченные атрибутом deleted=true.
  6. Модуль проставляет ссылки в данных.
  7. Обновление поискового индекса, urlrewrite, сброс кэша // Вы ведь не забываете делать все это при релизах :) ?

Вывод логов предыдущей команды (команда log)

Если при выполнении одной из предыдущих команд произошла ошибка, увидеть их можно командой log. Использовав опцию --fails можно отфильтровать все записи, оставив только сообщения об ошибках. Если же вам удобнее работать с БД, то все ошибки сохраняются в таблице intervolga_migrato_log.

Генерация демо-контента (команда для разработчиков generate)

Помните, трава раньше была зеленее, мороженое вкуснее а модуль DEFA Tools был бесплатным? Его генератор демо-контента мы воспроизводить, конечно, не стали, но добавить по 2 записи в каждую сущности команда generate может. Команда полезна для разработчиков новых сущностей.

Тестирование модуля (команда для разработчиков unittest)

Вторая команда, полезная для разработчиков (и тестировщиков). Исполняется сценарий.
  1. export;
  2. Файлы XML копируются в /local/migrato_old/;
  3. import;
  4. export;
  5. 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>
Значение поля

Как пользоваться модулем

Чтобы начать использовать модуль необходимо на боевом сайте создать оригинальный слепок БД:
  1. Установить модуль intervolga.migrato;
  2. Настроить /local/migrato/config.xml;
  3. validate.
autofix при необходимости или ручное исправление XML ID в БД:
  1. export
  2. Добавить папку /local/migrato/ в git (он же у вас уже есть)
  3. git commit & git push
  4. Снять бекап с prod и развернуть на dev1, dev2...
Чтобы подготовить миграцию на песочнице devX после окончания работы над задачей:
  1. validate
  2. autofix при необходимости или ручное исправление XML ID в БД
  3. export
  4. git commit & git push.
Выполнить миграцию (релиз) на боевом сайте:
  1. validate;
  2. autofix при необходимости;
  3. export (вдруг на бою были неучтённые в git’е изменения?);
  4. git commit при необходимости;
  5. git pull разрешение конфликтов, если возникли;
  6. git push, если возникли конфликты;
  7. 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. merge_migration_article
Как только все конфликты разрешены, программист должен вытолкнуть изменения на сервер.

После того, как все программисты вытолкнули свои изменения, версия базы данных в системе управления версий стабилизируется. Это значит, что наступило время делать релиз. После которого, чтобы обновить любой сайт (будь то сайт для разработки или prod), достаточно трех глобальный вещей:
  • Выполнить pull;
  • Проверить config файл (какие именно модули и сущности нам нужны);
  • Выполнить импорт данных.
В результате, каждый сайт имеет актуальную версию базы данных со всеми изменениями. Будь то удаление, создание или изменение записи с конфликтами или без, наш модуль превосходно справился с поставленными задачами.

Вместо выводов

Инструмент для миграции изменений БД жизненно необходим при ответственной командной работе над проектами. До сегодняшнего дня эта задача в мире 1С-Битрикс решалась очень плохо.

Мы же разработали промышленное решение этой задачи и отдаем его бесплатно всем желающим. Пользуйтесь, предлагайте улучшения, участвуйте в развитии, мы будем рады. Чтобы получить ссылку на установку модуля миграций для Битрикс, “поделитесь” статьей в соцсетях и укажите ссылку в форму под статьей. Ссылка на репозиторий с документацией придет вам на почту.
Оцените статью
24.07.2017
Понравилась статья?
Поделитесь ссылкой с друзьями и коллегами!

Статьи по теме

Выжимаем максимум скорости из PHPКогда дело доходит до запуска PHP-приложений, выбор подходящего веб-сервера критически важен. Цель статьи — помочь в выборе оптимального решения для своих проек...
Организация поиска на сайте: выбираем между поиском Битрикса, Sphinx и ElasticsearchВ статье разбираем популярные поисковые движки, чтобы выбрать лучший под задачи конкретного проекта. Даем советы по индексации каталога и построении «умного» фи...
Доработка системы LMS KnomaryMust have для бизнеса, где главный актив это люди, — стратегия обучения и развития персонала. Рассказываем как помогли доработать LMS-систему для компании ЕВРАЗ...
«Как раньше» больше не работает — B2B-система продаж сейчасВ этой статье хотим поговорить с чем сейчас сталкивается оптовый бизнес (множеством вызовов и изменений, которые требуют адаптации, а также оптимизации процессо...
Интеграция B2B-платформы на Битрикс с системой авторизации KeycloakВ период бурного роста компании менеджмент учетных записей сотрудников и клиентов может стать проблемой. Решение — интеграция с брокером авторизаций Keycloak ил...
Разработка календаря бронирования для сайта на Битрикс авиационного учебного центраЧтобы пилоты авиакомпаний могли бронировать время своих тренировок в учебном центре, мы разработали для них удобный модуль бронирования времени. Рассказываем по...
Мы работаем по одному из двух форматов:
  • аренда команды (от 2 человек, не менее 3 месяцев);
  • итерации с фиксированной ценой (1-3 месяца длительностью).
ИНТЕРВОЛГА предоставляет:
  • регулярные онлайн-планерки с заказчиком;
  • квалифицированных специалистов;
  • организованную команду (находятся в одном помещении, что упрощает решение рабочих вопросов);
  • полную прозрачность и регулярность отчетов о результатах.
Ключевые услуги:
  • нагруженный интернет-магазин;
  • личный кабинет;
  • оптовые продажи — B2B-платформа;
  • маркетплейс;
  • технический аудит сайта;
  • Битрикс24 — корпоративные HR-порталы;
  • Битрикс24 — построение CRM-системы;
  • Битрикс24 — личные кабинеты сотрудников;
  • Битрикс24 — аудит портала;
  • 1С — интеграция с другими системами;
  • 1С — доработка системы;
  • маркетинг — комплексное интернет-продвижение;
  • маркетинг — продвижение для B2B.
Хотите получать лучшие статьи от INTERVOLGA раз в месяц?
Подпишитесь на рассылку — спамить не будем