Про миграции в Битриксе

Так уж сложилось, что в 1С-Битрикс нет никакой штатной возможности по работе с модификацией структуры БД, кроме как делать это ручками в админке.

На конференциях разработчиков, у сотрудников Битрикса постоянно просят добавить в продукт механизм миграций БД, однако нам постоянно отвечают «завтраками», что может быть, когда-нибудь мы их сделаем.

Ну а работа не стоит на месте, потребность вносить изменения в БД в автоматическом режиме с соблюдением версионности никуда не делась, и даже наоборот — зреет с каждым днем.

Надоело! Прикручиваем миграции к Битриксу сами

Как обычно, любую задачу я начинаю с изучения того, что есть в опенсорсе. Для решения проблемы миграции уже есть несколько библиотек для битрикса, которые успешно применяются на продакшене.

worksolutions/bitrix-module-migrations

На момент написания статьи данный модуль является наиболее продвинутым из тех, что мне удалось найти, с точки зрения интеграции с битриксом. Это полноценный модуль, который можно установить из marketplace. Доступны исходники на Github.

Из плюсов стоит отметить, что модуль обладает как графическим интерфейсом в админке Битрикса, так и интерфейсом командной строки. Он позволяет наглядно видеть, какие миграции, когда и кем были применены, позволяет легко откатить уже выполненные миграции также через веб-интерфейс с полным логированием всех операций. Если возможность использовать «автомиграции»: это такая штука, которая слушает обработчики событий и при изменении схемы данных позволяет записать их изменение в файл с миграцией. Также у модуля есть подробно составленная документация с описанием большинства операций, которые можно выполнять с помощью модуля. А еще у них есть удобный функционал для упрощения написания скриптов миграций, т.н. билдеры, которые реально ускоряют процесс написания своей миграции.

Но для меня этот модуль не подошел. Частично из-за тех же плюсов, которые с другой стороны являются минусами. Да, исходники доступны на гитхабе, но они в windows-1251 (очевидно, для удобства публикации модуля в marketplace). Содержать свой форк в utf-8 будет накладно.
Сами создатели модуля обязывают устанавливать модуль из маркетплейса, т.к. при установке и обновлении производятся определенные операции изменения БД.
Ну и все описанное выше делает невозможным подключение модуля через composer, а также делает невозможным его обновление при отсутствующей лицензии.
В дополнение к этому, я очень опасаюсь, что модуль миграций каким-то образом может заинтересовать администратора сайта, и он может случайно, или намеренно применить или откатить ряд миграций, что может сказаться на функциональности сайта.
Workflow работы с миграциями меня тоже не очень порадовал: версия БД почему-то хранится в файле. А еще хеши, за которыми иногда придется следить.

В связи с этим всем я отказался от использования данного модуля, хотя он почти полностью покрывает мои нужды.

Phinx

Чудесная библиотека для создания миграций. Используется во многих проектах, но не имеет никакой нативной интеграции с битриксом (оно и понятно). Обладает всем необходимым функционалом для работы с БД, конфигурируется с помощью YML или php файлов. Но для упрощения работы с ним в битриксе пришлось бы написать определенный слой, в котором будет осуществляться помощь для создания миграций.

Честно признаться, я и не особо много изучал его возможности, а их у него предостаточно. Это навело на мысль, что возможно мне пока не нужен такой гигант на проекте, пока вокруг него не будет построена инфраструктура, помогающая в более простом и удобном виде создавать миграции, специфичные под Битрикс, а времени на подробное изучение библиотеки пока нет. Но Phinx однозначно заслуживает внимания, отложим его до лучших времен.

arrilot/bitrix-migrations

Эта библиотека оказалась для меня золотой серединой. Сделанная Ильёй Некрасовым из Greensight, простая, в основе которой лежат компоненты symfony и laravel, легко подключается через composer. Работа с библиотекой строится настолько просто и очевидно, что изучение возможностей укладывается в полчаса-час. Для упрощения и ускорения написания миграций для битрикса есть функционал «шаблонов», который содержит куски предустановленного кода. Также, как и в worksolutions/bitrix-module-migrations, есть возможность автоматически следить за изменениями схемы данных некоторых сущностей и создавать файлы миграций.
В общем говоря, простота модуля, его расширяемость, отсутствие административного интерфейса и следование стандартам подкупило меня, и я решил использовать именно его.

Интегрируемся

Я не упомянул еще одного факта, который был также важен при принятии решения. В проекте, на котором мне понадобились миграции, в качестве консольного приложения используется console-jedi, и мне было важно быстро и просто интегрироваться с ним. Благо, это не составило никакого труда.

Библиотека миграций предоставляет перечень следующих команд: install, make, migrate, rollback, templates, status. Каждая команда выполнена с помощью Symfony Console Component. В console-jedi я хотел видеть эти команды в отдельном пространстве имен, чтобы не путать с командами самого console-jedi. Сказано — сделано.

сonsole-jedi позволяет встроить в себя команды из приложения двумя способами. Первый способ — встроить с помощью модуля. В корне вашего битриксового модуля должен находиться файлик cli.php, который должен возвращать массив вида

О втором способе я расскажу чуть ниже.
У нас в команде как раз есть подходящий для использования первого способа модуль — maximaster/tools, в который было бы круто прикрутить миграции, и дать возможность всем разработчикам при подключении данного модуля использовать миграции на любом проекте.

Для интеграции в maximaster/tools нужно было сделать несколько простых шагов:

  1. Добавить зависимость maximaster/tools от arrilot/bitrix-migrations и notamedia/console-jedi
  2. Написать небольшой класс-адаптер, который позволит инициализировать модуль миграций и консольные команды. Тут я разделил команды на 2 вида — файловые и БДшные, ниже поясню, зачем именно. В методе addNamespaceToCommands я добавил неймспейс migrate для всех инициализированных команд.
  3. Поскольку модуль миграций рассчитывает на то, что ядро уже инициализировано полностью в момент запуска, а console-jedi работает несколько иначе, то нужно было создать небольшой враппер для класса работы с БД из модуля миграций. Единственная его цель — предоставить подключение к БД в случае, если ядро инициализировалось. Исходники можно посмотреть на гитхабе, там все тривиально.
  4. Подключить команды в cli.php в корне модуля:

    И вуаля!

migration-commands

Файловые и не файловые команды

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

Так вот разделение команд на файловые и не файловые необходимо было для того, чтобы дать разработчикам возможность пользоваться файловыми командами миграций на своем локальном ПК даже не имея веб-сервера и битрикса. console-jedi устроен таким образом, что он будет работать и без битрикса, но команды будут доступны не все. Я решил использовать и эту возможность.

maximaster/tools — это не совсем типичный модуль в понятии Битрикса. Он не использует нативную автозагрузку битрикса, благодаря чему его классы тоже можно использовать и вне битрикса. Поэтому подключив модуль через composer, вы получаете тот же модуль миграций и адаптер к нему, которые можно использовать благодаря psr-4.

В jedi есть еще один способ добавления команд — через файл .jedi.php в корне проекта. Схема примерно та же, что и в cli.php но в нем мы зарегистрируем только файловые операции:

после чего на локальном компе будут доступны операции миграций — создание файла и просмотр списка шаблонов миграций:

migration-file-commands

Да, джедай будет ругаться на отсутствие битрикса, но это и ожидалось. Но зато теперь на любом ПК разработчика будут доступны команды, упрощающие создание миграций. Создав файл миграции через migration:make не придется идти по ssh на сервер разработки и выкачивать нужную миграцию (особенно когда их будут сотни и тысячи)

Вот такая получилась полезная интеграция!

Я не сомневаюсь, что и для Phinx и для ws.migrations можно сделать подобную интеграцию. Коллеги из Notamedia (спасибо им за console-jedi), кстати как раз используют Phinx в своих проектах, который интегрирован с джедаем. Данная статья больше о том, каким путем я пошел для подключения миграций в Битрикс, а не о том, каким именно инструментом пользоваться для этого.

Спасибо за внимание.