Открыть список
Как стать автором
Обновить

Комментарии 24

Например, миграции Entity Framework почему-то обязательно должны быть в одной сборке с DbContext

Это не совсем так. Вы можете указать другую сборку при настройке контекста. Например так:

services.AddDbContextPool<Context>(options =>
{
     options.UseNpgsql("connection string",
         builder => builder.MigrationsAssembly("some assembly"));
});
О, спасибо! Почему-то раньше этого не нашел. Буду иметь в виду.
Во FluentMigrator можно заменить реализацию IMigrationInformationLoader и IVersionLoader на свои…
Спасибо! В документации про это ничего нет, поэтому не нашел его. Попробую разобраться в коде, как будет время.
Мне, как пользователю, в миграции нужны следующие вещи:
1) Создание автодифов по двум коннекшенам (ну т.е. я сам как угодно ворочу базой, а мне потом выдается готовый скрипт/dsl и т.д.).
2) Reduce через несколько версий, например сейчас актуальная версия 4, но есть база с версией 2, мигратор это все видит и вычисляет шаги с 2 по 4, отбрасывая некоторые элементы (например, в версии 3 была удалена таблица, а в 4 я ее опять добавил и при миграции с 2 на 4 — мы этот шаг пропускаем, а не удаляем и создаем еще раз).

К сожалению, такого нигде найти не смог, и поэтому все руками.
Выглядит, как будто вы хотите получать diff двух состояний БД. Это немного другой подход. Для этого даже не нужны номера версий.

В простых случаях он позволяет делать руками меньше действий для обновления БД. В сложных случаях может потребоваться сложная магия. Такие инструменты тоже существуют (кажется в Visual Studio раньше была такая штука), но они, как правило, сложные, дорого стоят и них графический интерфейс (чтобы человек контролировал правильность того, что получилось).

Версионная миграция БД — второй подход, в котором вы описываете инкрементальные изменения (т.е. изменения для перехода от текущей версии к следующей). Этот подход выигрывает в плане простоты и надежности. Его легко автоматизировать.
С версионным подходом все ясно. Тут дело в другом, что все те миграторы, что я смотрел и использовал просили ручного труда. А мне бы хотелось, чтобы мигратор оперировал неким diff для перехода из одной версии к другой и все это вычислял сам, через две базы (одна production, другая develop). Есть такие diff утилиты (и я ими активно пользуюсь), но они на выходе дают голый SQL, поэтому я и пишу — «все руками».
Согласен такая отдельная утилита была бы очень полезна.
Например, я в процессе ускорения работы базы. Добавляю прямо в нее индексы, новые колонки, таблицы. И тут ты понимаешь что все это надо повторить в миграции — я бы прыгал от счастья если бы мне сгенерили миграцию по diff, которую я бы ревьювнул и добавил в проект.
Пользоваться автогенерировангыми скриптами для миграции продакшен БД можно только если данные в ней не нужны, а вывести систему в даунтайм на час другой вообще не разу не проблема.
автогенерировангыми скриптами для миграции продакшен БД можно только если данные в ней не нужны

Это кто так сказал?
Или Вы за то, что писать весь SQL «руками»?
Это мне опыт говорит. Я за то чтобы думать когда применяешь к продакшен БД какие либо скрипты. Автогенеренные или «самописные» не важно. Не важно как именно вы их получили, от разработчиков которые их писали руками на каждый таск в jira или с помощью сравнения БД и текущего проекта БД каким нибудь инструментом типа SSDT.
Перед тем как применять их к продакшен их нужно проанализировать, возможно переписать какие-то части чтобы, 1) минимизировать вероятность потери данных, 2) сократить время миграции данных 3) исключить взаимоисключающие действия: добавили колонку, потом передумали и удалили колонку (в случае самописных скриптов) 3) сократить или исключишь даунтайм БД (иначе какой смысл в Green blue deployment?)
У MS этот инструмент называется SQL Server Data Tools
Пользовался, но там многие огрехи руками приходилось исправлять.
А бывают реально случаи, когда надо даунгрейдить базу? Это же обычно с потерей данных происходит, что звучит совсем критично.
это случае такого же масштаба, что и восстановление рухнувшей базы с последнего бэкапа. Т.е. очень желательно иметь процедуру реверса/отката, но не использовать ее на практике.
То, что не используется на практике, никогда не будет работать. Ну, формально будет, но криво, неожиданно и прочая.
Да. Это происходит при слиянии веток где успели накопиться свои миграции.
Можете расписать подробнее?

Т.е. я пилил фичу А, со своими миграциями. В мастер залили фичу Б, со своими миграциями.

Я вмержил мастер себе — получил миграции Б, накатил их. Где даунгрейд?
Во-первых, миграции запросто могут конфликтовать. Во-вторых, некоторые миграторы нумеруют миграции — и в таком случае можно получить конфликт номеров даже при отсутствии других конфликтов.

В обоих случаях придется откатывать свои миграции перед мержем мастера.
Эм, откатывать, а не смержить миграции? Не понимаю всё равно.
Сначала откатить, потом смержить и накатить обратно.

Использую dotnet ef add migration с дополнительным инструментом сидирования при миграции (в момент накатывания миграции на базу можно исполнить любой код). Пока не подводил, единственно, что иногда нужно контролировать тот sql, который он сгенерировал.

В EF6 была очень удобная с точки зрения быстрой разработки прототипа или домашнего проекта концепция автоматических миграций. Достаточно было зарегистрировать мигратор при старте приложения или в веб.конфиге, например,
<databaseInitializer type="System.Data.Entity.MigrateDatabaseToLatestVersion`2[[GreatPlace.Data.GreatPlaceContext, GreatPlace.Data], [GreatPlace.Data.MigrationConfiguration, GreatPlace.Data]], EntityFramework" />

Я ей часто пользовался, это экономило кучу времени на начальных этапах разработки. К сожалению, для EF Core такого мигратора нет и не планируется (здесь обсуждение: github.com/aspnet/EntityFrameworkCore/issues/6214). Найти что-то стороннее тоже не получилось. Писать свое решение — сложно и долго. Может быть, вы сталкивались с чем-то похожим, или вашу библиотеку можно приспособить для этой задачи относительно просто?

При условии, что вы пишете seed’в есть такое «костыль»: делаете батник с миграцией init, пишете код, удаляете миграции, вызываете init и migrate. В каждый момент у вас одна миграция. Менее изящно, но на этапе прототипирования бывает удобно. Если pk надо заменить, например.

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