Сборка VSTS - инкрементное развертывание базы данных в распределенной среде
У меня есть база данных sql server, работающая с приложением.net 2015 mvc 5. Код моей базы данных контролируется исходным кодом с использованием проекта SSDT. Я использую SqlPackage.exe для развертывания базы данных в промежуточной среде с использованием файла.Decpac, созданного в процессе сборки проекта SSDT. Это было сделано с помощью задачи powershell сборки VSTS. Таким образом, я могу вносить изменения в схему БД в режиме, контролируемом исходным кодом. Теперь проблема касается вставки основных данных для базы данных.
Я использую файл сценария sql, в котором есть сценарии вставки данных, которые выполняются как сценарий после развертывания. Этот файл также контролируется источником.
Проблема заключается в том, что изначально мы подготовили скрипт вставки для целевого спринта (взяв в качестве основы спринт n), который хорошо работает для первого выпуска. но в следующем спринте, если обновите некоторые основные данные, то как следует обновить вставку основных данных:
- Добавить новый запрос на обновление / вставку в конце файла скрипта? но в этом случае сценарий после развертывания будет выполняться CI, и он попытается вставить данные снова и снова в последующих сборках, что в итоге приведет к сбою, если мы внесем некоторые изменения в схемы в основных таблицах этой базы данных.
- Обновите существующие запросы вставки в скрипте вставки данных. в этом случае у нас также возникают проблемы, потому что при событии после сборки все данные будут вставлены заново.
- Ведение отдельных сценариев вставки данных для каждого сценария и обновление ссылки на сценарий на новый файл для события после построения SSDT. Этот подход требует ручного усилия и ошибки, потому что разработчик должен помнить этот процесс. Также другая проблема с этим подходом заключается в том, что нам нужно настроить еще 1 сервер базы данных в распределенной ферме серверов. Сценарий множественной вставки данных выдаст ошибки, потому что SSDT имеет последнюю схему и создаст базу данных с той же самой. но в старых сценариях данных есть вставка данных для предыдущей схемы (спринт-схема БД, которая была изменена в более поздних спринтах)
Таким образом, любой может предложить лучший подход, который требует меньших ручных усилий, но может охватывать все вышеупомянутые случаи.
Спасибо Рупендра
3 ответа
Убедитесь, что ваши сценарии до и после развертывания всегда идемпотентны. Однако вы хотите реализовать это на ваше усмотрение. Скрипты должны запускаться любое количество раз и всегда давать правильные результаты. Поэтому, если ваша схема изменится, что повлияет на сценарии развертывания, обновление сценариев является зависимостью от изменений и сопровождает ее в управлении исходным кодом. Управление версиями вашей базы данных уже является встроенной функцией SSDT. В самом файле проекта есть узел для версии. И в VSTS есть целый ряд задач создания версий, которые вы можете использовать для бесплатной версии. Когда SqlPackage.exe публикует ваш проект с уже установленной версией базы данных, запись обновляется в msdb.dbo.sysdac_instances. Это намного проще, чем пытаться управлять, обновлять и т. Д. Собственное решение для собственной версии. И вы не загромождаете базу данных своего приложения таблицами и другими объектами, не связанными с самим приложением. Я согласен с тем, чтобы не допустить информацию о спринте. В наших проектах я помечаю источник при успешных сборках номером сборки, что, конечно, создает маркер на определенный момент времени в источнике, который связан с конкретной сборкой.
То, что я сделал на большинстве проектов, это создать MERGE
скрипты, по одному на таблицу, которые заполняют "основные" или "статические" данные. Существуют такие инструменты, как https://github.com/readyroll/generate-sql-merge которые можно использовать для создания этих сценариев.
Они вызываются из сценария после развертывания, а не из действия после сборки. Обычно я создаю для проекта один сценарий (в любом случае разрешен только один!), А затем включаю все отдельные сценарии статических данных, используя :r
синтаксис. Сценарий после развертывания - это просто .sql
файл с действием сборки "Post-Deploy", его можно создать "вручную" или с помощью диалогового окна "Добавить новый объект" в SSDT и выбрать "Сценарий -> Сценарий после развертывания".
Эти файлы (включая сценарий после развертывания) могут затем быть версии вместе с остальными исходными файлами; если вы внесете изменение в определение таблицы, которое требует изменения в merge
Заявление, которое заполняет данные, то эти изменения могут быть зафиксированы вместе.
Когда вы создаете DACPAC, все основные данные будут включены, и так как вы используете merge
вместо вставки вы гарантируете, что в конце развертывания содержимое таблиц будет соответствовать содержимому элемента управления исходным кодом, так же как SSDT/sqlpackage гарантирует, что структура ваших таблиц соответствует структуре их определений в управлении исходным кодом.
Мне не ясно, как понятие "спринт" входит в это, если "спринт" не означает "выпуск"; в этом случае dacpac, созданный и выпущенный в конце спринта, будет содержать все изменения, как структурные, так и "основные данные", добавленные во время спринта. Я думаю, что, вероятно, разумно держать понятие "спринт" далеко от вашего контроля над источниками!
Я бы предложил использовать операторы MERGE вместо insert. Таким образом, вы защищены от дублированных вставок в области спринта.
Следующее, как отличить разные вставки для разных спринтов. Я бы предложил реализовать нумерацию версий для синхронизации базы данных со спринтами. Поэтому создайте таблицу DbVersion(версия int). Затем в сценарии после развертывания сделайте что-то вроде этого:
SET @version = SELECT ISNULL(MAX(version), 0) FROM DbVersion
IF @version < 1
--inserts/merge for sprint 1
IF @version < 2
--inserts/merge for sprint 2
...
INSERT INTO DbVersion(@currentVersion)