Porównanie i wybór systemów migracji danych

Model danych w procesie rozwoju ma właściwość zmienności i w pewnym momencie przestaje odpowiadać bazie danych. Oczywiście bazę danych można usunąć, a wtedy ORM stworzy nową wersję, która będzie odpowiadać modelowi, ale taka procedura prowadzi do utraty istniejących danych. W ten sposób funkcja systemu migracji sprowadza się do synchronizacji schematu z modelem danych w aplikacji bez utraty istniejących danych.
W ramach tego artykułu chcielibyśmy przyjrzeć się różnym narzędziom do zarządzania migracjami baz danych. Mamy nadzieję, że ten przegląd będzie pomocny dla programistów, którzy stanęli przed podobnym wyborem.
Zadanie
W naszej firmie obecnie prowadzony jest intensywny rozwój następnej generacji produktu - Docs Security Suite (DSS). Część serwerowa jest pisana w .Net Core, a jako bazę danych wykorzystywany jest odpowiednio Entity Framework Core. Przy projektowaniu aplikacji stosujemy podejście Code First.
Domenowa model aplikacji jest tworzona równocześnie przez kilku programistów - każdy odpowiada za swoją logiczną część systemu.
W poprzedniej generacji DSS jako system zarządzania migracjami wykorzystywano klasyczne Entity Framework Migrations (EF 6). Jednakże zgromadziło to pewne pretensje, z których główną była niewystarczająca strategia rozwiązywania konfliktów wersji. Fakt ten wciąż nas martwi podczas naprawy błędów w ramach wsparcia, dlatego podjęto decyzję o rozważeniu alternatywnych opcji.
W wyniku dyskusji sformułowano następujące wymagania dla systemu zarządzania migracjami:
- Wsparcie różnych systemów baz danych. Obowiązkowe MS SQL Server, PostgreSQL, Oracle, ale potencjalnie możliwe jest również wykorzystanie innych.
- Współpraca z ORM. Początkowo zakładano użycie EF Core, jednak na etapie projektowania byliśmy gotowi rozważyć inne ORM.
- Autogenracja migracji. Biorąc pod uwagę rozwój Code First, chcielibyśmy uniknąć konieczności ręcznego przygotowywania migracji.
- Konflikty wersji. W warunkach rozproszonego rozwoju podczas scalania EF Core może napotykać konflikty. To staje się poważnym problemem, ponieważ różne części aplikacji są tworzone przez różnych programistów, co prowadzi do dużych nakładów czasowych na każde skalowanie.
- Rozbudowana dokumentacja i wsparcie. Tutaj, naszym zdaniem, nie są potrzebne dodatkowe wyjaśnienia.
- Darmowość. Kryterium umowne, ponieważ również rozważylibyśmy nieco droższe systemy albo drogie, ale idealne pod względem wygody.
W wyniku niewielkiego badania znaleziono i uznano za warte rozważenia następujące opcje:
- Migracje EF Core
- DBup
- RoundhousE
- ThinkingHome.Migrator
- Fluent Migrator
A teraz nieco więcej szczegółów.

Oczywiście, to była pierwsza i podstawowa opcja do rozważenia. Narzędzie natywne, działające od razu bez żadnych sztuczek. Duża ilość dokumentacji, zarówno oficjalnej, jak i nieoficjalnej, prostota itd. Jednak zarzuty, które stawiano klasycznemu EF, są również jak najbardziej aktualne dla EF Core.
W związku z tym dla EF Core wyróżnia się zalety:
- Wsparcie Microsoft, dokumentacja, w tym w języku polskim, ogromna społeczność.
- Autogeneza migracji na podstawie CodeFirst.
- W porównaniu do EF 6, w EF Core nie przechowuje się już zrzutu bazy danych. Pracując z EF Core w Code First, nietak konieczne jest uruchamianie bazy danych.
- Ponieważ wychodzimy od Code First - istnieje możliwość prowadzenia jednej migracji dla wszystkich wymaganych dostawców dostępu do danych.
- Jeśli chodzi o dostawców – obsługiwane są zarówno PostgreSQL, jak i Oracle, itd., a nawet – MS SQL Server.
A także wady:
- Rozwiązywanie konfliktów pozostało na tym samym poziomie. Należy ustalać kolejność migracji i aktualizować zrzuty bazy danych.
- Zależność od modeli, na podstawie których generowane są migracje.
DbUp

DbUp to biblioteka .NET, która jest instalowana przez NuGet i pomaga wprowadzaniu zmian do SQL Server. Śledzi, które skrypty zmian już zostały zrealizowane, i uruchamia te, które są potrzebne do aktualizacji bazy danych. Biblioteka wyrosła z projektu otwartego silnika blogów na platformie ASP.NET i istnieje na licencji MIT, a kod znajduje się na GitHubie. Migracje są opisywane za pomocą T-SQL.
Jakie są tu zalety:
- Wsparcie dla dużej liczby systemów DBMS (MS SQL Server, PostgreSQL, MySQL).
- Ponieważ skrypty pisane są w T-SQL, wyglądają dość prosto.
- Konflikty również rozwiązuje się przy pomocy SQL.
A wady:
- Pomimo bogatego asortymentu wspieranych DBMS, Oracle do nich nie należy.
- Nie współpracuje z ORM.
- Pisanie skryptów w T-SQL ręcznie – nie jest tym, do czego dążyliśmy.
- Dokumentacja i społeczność są przeciętne, chociaż w kontekście pisania skryptów SQL mogą być zbędne.
RoundhousE

To narzędzie do zarządzania migracjami, udostępniane na licencji Apache 2.0, podobnie jak poprzednie, działa na silniku migracji T-SQL. Wygląda na to, że deweloperzy skupili się na rozwiązaniu problemów technicznych w zakresie wsparcia dla DBMS, a nie na tworzeniu wygodnego procesu rozwoju.
Zalety:
- Obsługuje niezbędne DBMS (w tym Oracle)
Wady:
- Oracle (a także nieaktualny dla nas Access) nie jest wspierany na .NET Core, tylko na .NET Full Framework
- Nie działa z ORM
- Dokumentacja jest jeszcze uboższa niż w przypadku poprzedniego narzędzia
- Ponownie – migracje są pisane w skryptach
ThinkingHome.Migrator
![]()
Narzędzie do wersjonowania migracji schematu bazy danych na platformę .NET Core, udostępniane na licencji MIT. .
Zalety:
- Dostosowane do .NET Core
- Zrealizowano rozgałęzioną sekwencję migracji
- Zrealizowano logowanie migracji
Wady:
- Ostatnia aktualizacja – rok temu. Wygląda na to, że projekt nie jest wspierany
- Nie wspiera Oracle (w artykule podano, że to z powodu braku stabilnej implementacji pod .NET Core – ale miało to miejsce rok temu)
- Brak automatycznej generacji migracji
Ogólnie rzecz biorąc, projekt wygląda obiecująco, szczególnie gdyby się rozwijał, ale musieliśmy podjąć decyzję tutaj i teraz.
Fluent Migrator

Najbardziej popularne narzędzie do migracji, posiadające dużą rzeszę zwolenników. Udostępniane na licencji Apache 2.0. Jak wskazano w opisie, jest platformą migracji dla .NET, analogiczną do Migracji Ruby on Rails. Zmiany w schemacie bazy danych są opisywane w klasach w C#.
Są pewne zalety:
- Wsparcie dla niezbędnych DBMS
- Wsparcie dla .NET Core
- Duża rozwinięta społeczność
- Konflikty migracji są rozwiązywane sekwencyjnie – każda migracja ma określony porządek wykonania. Dodatkowo, jeśli występuje konflikt wokół jednej encji, podczas scalania kodu rozwiązanie jest przeprowadzane tak samo, jak w reszcie kodu
- Są profile, które są uruchamiane po pomyślnym wykonaniu migracji i mogą pełnić funkcje serwisowe. Ostatnia aktualizacja miała miejsce miesiąc temu, więc projekt wciąż się rozwija.
Jeśli chodzi o minusy, to jest tu:
- Brak automatycznej generacji migracji
- Brak powiązania z modelami EF
- Brak zrzutów bazy danych
Jaki był więc nasz wybór?

Największe kontrowersje wywołały dwa parametry – automatyczne generowanie migracji oraz rozsądne rozwiązanie konfliktów. Inne czynniki budziły znacznie mniejsze obawy. W rezultacie, po dyskusji zespół podjął decyzję o zastosowaniu Fluent Migrator w nowym projekcie. Rozwiązanie konfliktów w dłuższej perspektywie przyniesie znacznie więcej korzyści.
Wnioski
Oczywiście, nie ma idealnych narzędzi. Dlatego przy wyborze musieliśmy ustalić priorytety w naszych „chęciach”. Jednak dla innych zespołów i zadań mogą decydujące okazać się inne czynniki. Mamy nadzieję, że ten artykuł pomoże w podjęciu decyzji.
Źródło: habr.com
