Сравнение и выбор систем миграции данных
Модель данных в процессе разработки имеет свойство изменяться, и в какой-то момент она перестает соответствовать базе данных. Конечно же, БД можно удалить, и тогда ORM создаст новую версию, которая будет соответствовать модели, но такая процедура приведет к потере существующих данных. Таким образом, функция системы миграции сводится к тому, чтобы в результате изменения схемы синхронизировать ее с моделью данных в приложении без потери существующих данных.
В рамках данной статьи нам хотелось бы рассмотреть различные инструменты для управления миграциями баз данных. Надеемся, этот обзор будет полезен для разработчиков, столкнувшихся с подобным выбором.
Задача
В нашей компании сейчас ведется активная разработка следующего поколения продукта – Docs Security Suite (DSS). Серверная часть пишется на .Net Core, и в качестве СУБД соответственно используется Entity Framework Core. При проектировании приложения мы используем подход Code First.
Доменную модель приложения создают несколько разработчиков одновременно – каждый отвечает за свою логическую часть системы.
В предыдущем поколении DSS в качестве системы управления миграциями использовался классический Entity Framework Migrations (EF 6). Однако, к нему накопились некоторые претензии, главная из которых заключалась в том, что в EF отсутствует вменяемый подход к разрешению конфликтов версий. Этот факт до сих пор нас огорчает при багфиксинге в рамках поддержки, поэтому было принято решение рассмотреть альтернативные варианты.
В результате обсуждения сформировались следующие требования к системе управления миграциями:
- Поддержка различных СУБД. Обязательно MS SQL Server, PostgreSQL, Oracle, но потенциально возможно использование и других
- Работа с ORM. Изначально предполагалось использование EF Core, однако на этапе проектирования были готовы рассмотреть и другие ORM
- Автогенерация миграций. С учетом разработки Code First необходимости «расписывать ручками» миграции хотелось бы избежать
- Конфликты версий. В условиях распределенной разработки при мерджинге EF Core может валиться на конфликтах. Это становится существенной проблемой, поскольку различные части приложения создаются разными разработчиками, поэтому приходится тратить большое количество времени на каждый
- Развитая документация и поддержка. Здесь, нам кажется, пояснения не нужны
- Бесплатность. Критерий условный, поскольку не очень дорогие системы или дорогие, но идеальные в удобстве, мы тоже готовы были рассмотреть
В результате небольшого исследования были найдены и признаны желательными для рассмотрения следующие варианты:
- EF Core Migrations
- DBup
- RoundhousE
- ThinkingHome.Migrator
- Fluent Migrator
А теперь чуть подробнее
EntityFramework Core Migrations
Естественно, это был первый и основной вариант для выбора. Нативный инструмент, работающий из коробки без каких-либо плясок с бубном. Большое количество документации, официальной и не очень, простота и т.д. Однако претензии, предъявлявшиеся к классическому EF, вполне актуальны и для EF Core.
Таким образом для EF Core выделены плюсы:
- Поддержка Microsoft, документация, в том числе на русском, огромное комьюнити
- Автогенерация миграций на основе CodeFirst
- По сравнению с EF 6 в EF Core теперь не хранится снимок БД. При работе с EF Core в Code First теперь не обязательно разворачивать базу данных
- Поскольку пляшем от Code First – есть возможность вести одну миграцию на все требуемые провайдеры доступа к данным
- По поводу провайдеров — поддерживается и PostgreSQL, и Oracle, и т.д., и т.п., и даже – MS SQL Server ?
А также минусы:
- Разрешение конфликтов осталось на том же уровне. Необходимо выстраивать последовательность миграций и обновлять снимки БД
- Зависимость от моделей, на основе которых сгенерированы миграции
DbUp
dbup.github.io
DbUp – это библиотека на .NET, которая устанавливается NuGet’ом и помогает накатывать изменения на SQL Server. Она отслеживает, какие скрипты изменений уже выполнены, и запускает те, которые необходимы для обновления БД. Библиотека выросла из проекта опенсорсного движка блогов на ASP.NET и существует под лицензией MIT, а код лежит на GitHub’е. Миграции описываются с помощью T-SQL.
Какие тут плюсы:
- Поддержка большого количества СУБД (MS SQL Server, PstgreSQL, MySQL)
- Поскольку скрипты пишутся на T-SQL, выглядят они довольно просто
- Конфликты также решаются с помощью SQL
А минусы:
- При всем многообразии поддерживаемых СУБД, Oracle в их число не входит
- Не взаимодействует с ORM
- Написание скриптов на T-SQL «ручками» – не то, к чему мы стремились
- Документация и комьюнити так себе, хотя в условиях написания SQL-скриптов они, может быть, и не нужны.
RoundhousE
github.com/chucknorris/roundhouse
Этот инструмент управления миграциями, распространяемый под лицензией Apache 2.0, как и предыдущий, работает на движке T-SQL миграций. Судя по всему, разработчики ставили во главу угла решение технических проблем в части поддержки СУБД, а не создание комфортного процесса разработки.
Плюсы:
- Поддерживает необходимые СУБД (включая Oracle)
Минусы:
- Oracle (а так же неактуальный для нас Access) не поддерживается на .NET Core, только на .NET Full Framework
- Не работает с ORM
- Документации еще меньше, чем у предыдущего инструмента
- Опять же – миграции пишутся скриптами
ThinkingHome.Migrator
Инструмент для версионной миграции схемы базы данных под платформу .NET Core, распространяемый под лицензией MIT. Сам разработчик писал про последнюю его версию почти год назад.
Плюсы:
- Заточен под .NET Core
- Реализована ветвистая последовательность миграций
- Реализовано логирование миграций
Минусы:
- Последнее обновление – год назад. Судя по всему, проект не поддерживается
- Не поддерживается Oracle (в статье указано, что это из-за отсутствия стабильной реализации под .NET Core – но это год назад)
- Отсутствует автогенерация миграций
В целом, проект выглядит перспективным, особенно если развивался бы, но нам необходимо было принимать решение здесь и сейчас.
Fluent Migrator
github.com/fluentmigrator/fluentmigrator
Наиболее популярный инструмент миграций, имеющий большую армию поклонников. Распространяется под лицензией Apache 2.0. Как указано в описании, является платформой миграции для .NET, аналогичная Ruby on Rails Migrations. Изменения схемы БД описываются в классах на C#.
Тут есть плюсы:
- Поддержка необходимых СУБД
- Поддержка .NET Core
- Большое развитое комьюнити
- Конфликты миграций решаются последовательно – у миграций указывается порядок выполнения. Кроме того, если возникает конфликт вокруг одной сущности, при мерджинге кода его решение производится так же, как и в остальном коде
- Есть профили, которые выполняются после успешного выполнения миграции. И могут нести в себе сервисные функцииПоследнее обновление было месяц назад, то есть проект живет
Что же до минусов, то тут:
- Отсутствует автогенерация миграций
- Отсутствует связь с моделями EF
- Нет снимков БД
Каков же был наш выбор?
Самые горячие споры развернулись вокруг двух параметров – автогенерация миграций и вменяемого решения конфликтов. Прочие факторы пугали гораздо меньше. В итоге, по результатам обсуждения командой было принято решение использовать в новом проекте Fluent Migrator. Ибо решение конфликтов в дальнейшей перспективе принесет гораздо большее количество плюсов.
Выводы
Конечно, идеальных инструментов не бывает. Вот и нам для выбора пришлось расставить приоритеты в наших «хотелках». Однако, для других команд и других задач могут оказаться решающими другие факторы. Надеемся, данная статья поможет вам сделать выбор.
Комментарии (7)
vagon333
29.05.2019 11:51Использовали custom решение на базе T-SQL скриптов с регистрацией накатки в базе.
Надежно, но не mainstream — у новых разработчиков сложности с пониманием и сложности с грамотным написанием T-SQL.
Перешли на Fluent Migrator.
У Fluent Migrator есть свойство — если в одной миграции несколько шагов и один из шагов вызывает ошибку на сервере баз данных, Fluent лихо продолжает выполнять шаги и оценивает результат выполнения по последнему шагу (как успех). Т.е. сложные миграции желательно дробить.
RouR
29.05.2019 14:30EF core
Разрешение конфликтов осталось на том же уровне. Необходимо выстраивать последовательность миграций и обновлять снимки БД
Не понял. Вы же сами пишете что в EF Core теперь не хранится снимок БД. А в других инструментах последовательность миграций может любой? Что-то сомневаюсь.
А для DbUp вы вообще в плюсы вписали «Конфликты также решаются с помощью SQL»
Зависимость от моделей, на основе которых сгенерированы миграции
В миграции можно написать выполнение любого необходимо sql-query. В plain-text, без зависимости от моделей.
VictorNS
30.05.2019 17:58В своё время ушли на Fluent с EF потому, что многое делает по умолчанию и не позволяет «допилить». Например нельзя задать имя DEFAULT CONSTRAINT для колонки. А иногда так уж складывается, что надо. Про отсутствии автогенерации не особо жалели. Ручками оно как-то надёжнее.
Ordos
Ещё одно решение для .net: github.com/lecaillon/Evolve
Выглядит очень похожим на Flyway
sanitto Автор
Спасибо.
Будем иметь в виду на будущее. :)