Сравнение и выбор систем миграции данных




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

В рамках данной статьи нам хотелось бы рассмотреть различные инструменты для управления миграциями баз данных. Надеемся, этот обзор будет полезен для разработчиков, столкнувшихся с подобным выбором.

Задача


В нашей компании сейчас ведется активная разработка следующего поколения продукта – Docs Security Suite (DSS). Серверная часть пишется на .Net Core, и в качестве СУБД соответственно используется Entity Framework Core. При проектировании приложения мы используем подход Code First.

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

В предыдущем поколении DSS в качестве системы управления миграциями использовался классический Entity Framework Migrations (EF 6). Однако, к нему накопились некоторые претензии, главная из которых заключалась в том, что в EF отсутствует вменяемый подход к разрешению конфликтов версий. Этот факт до сих пор нас огорчает при багфиксинге в рамках поддержки, поэтому было принято решение рассмотреть альтернативные варианты.

В результате обсуждения сформировались следующие требования к системе управления миграциями:

  1. Поддержка различных СУБД. Обязательно MS SQL Server, PostgreSQL, Oracle, но потенциально возможно использование и других
  2. Работа с ORM. Изначально предполагалось использование EF Core, однако на этапе проектирования были готовы рассмотреть и другие ORM
  3. Автогенерация миграций. С учетом разработки Code First необходимости «расписывать ручками» миграции хотелось бы избежать
  4. Конфликты версий. В условиях распределенной разработки при мерджинге EF Core может валиться на конфликтах. Это становится существенной проблемой, поскольку различные части приложения создаются разными разработчиками, поэтому приходится тратить большое количество времени на каждый
  5. Развитая документация и поддержка. Здесь, нам кажется, пояснения не нужны
  6. Бесплатность. Критерий условный, поскольку не очень дорогие системы или дорогие, но идеальные в удобстве, мы тоже готовы были рассмотреть

В результате небольшого исследования были найдены и признаны желательными для рассмотрения следующие варианты:

  1. EF Core Migrations
  2. DBup
  3. RoundhousE
  4. ThinkingHome.Migrator
  5. 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)


  1. Ordos
    29.05.2019 10:40

    Ещё одно решение для .net: github.com/lecaillon/Evolve
    Выглядит очень похожим на Flyway


    1. sanitto Автор
      29.05.2019 12:31

      Спасибо.
      Будем иметь в виду на будущее. :)


  1. vagon333
    29.05.2019 11:51

    Использовали custom решение на базе T-SQL скриптов с регистрацией накатки в базе.
    Надежно, но не mainstream — у новых разработчиков сложности с пониманием и сложности с грамотным написанием T-SQL.
    Перешли на Fluent Migrator.
    У Fluent Migrator есть свойство — если в одной миграции несколько шагов и один из шагов вызывает ошибку на сервере баз данных, Fluent лихо продолжает выполнять шаги и оценивает результат выполнения по последнему шагу (как успех). Т.е. сложные миграции желательно дробить.


  1. Soupbreak
    29.05.2019 12:27

    Почему не стали рассматривать liquibase?(https://www.liquibase.org/)


    1. sanitto Автор
      29.05.2019 12:31

      Liquibase, насколько я знаю, с .net core не самым лучшим образом дружит.

      В любом случае, все возможные существующие варианты рассмотреть не было возможности.


  1. RouR
    29.05.2019 14:30

    EF core

    Разрешение конфликтов осталось на том же уровне. Необходимо выстраивать последовательность миграций и обновлять снимки БД

    Не понял. Вы же сами пишете что в EF Core теперь не хранится снимок БД. А в других инструментах последовательность миграций может любой? Что-то сомневаюсь.
    А для DbUp вы вообще в плюсы вписали «Конфликты также решаются с помощью SQL»

    Зависимость от моделей, на основе которых сгенерированы миграции

    В миграции можно написать выполнение любого необходимо sql-query. В plain-text, без зависимости от моделей.


  1. VictorNS
    30.05.2019 17:58

    В своё время ушли на Fluent с EF потому, что многое делает по умолчанию и не позволяет «допилить». Например нельзя задать имя DEFAULT CONSTRAINT для колонки. А иногда так уж складывается, что надо. Про отсутствии автогенерации не особо жалели. Ручками оно как-то надёжнее.