Запустите сравнение схемы из конвейера Azure DevOps для обновления проекта базы данных SQL

#azure-devops #azure-pipelines #sql-server-data-tools

#azure-devops #azure-конвейеры #sql-server-data-tools

Вопрос:

У нас есть проект базы данных SQL, который мы используем для развертывания изменений в наших средах ТЕСТИРОВАНИЯ и разработки. В течение дня разработчики вносят изменения непосредственно в базу данных разработчиков (не используйте проект базы данных). Периодически в проекте базы данных выполняется сравнение схемы для сбора всех изменений, внесенных разработчиками в базу данных разработчиков, чтобы их можно было применить к ТЕСТОВОЙ среде через конвейер выпуска Azure.

Все это отлично работает в конвейерах Azure, но мы хотели бы создать конвейер, который автоматически запускает сравнение схемы между базой данных разработчиков и применяет изменения к проекту базы данных (мы должны сделать это вручную). Несколько лет назад я изучил это, и командная строка не поддерживала использование проекта базы данных в качестве цели для сравнения схемы. Кто-нибудь знает, возможен ли этот тип рабочего процесса в наши дни?

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

1. В течение дня разработчики вносят изменения непосредственно в базу данных разработчиков (не используйте проект базы данных). Прекратите это делать. Ваш непрерывный процесс доставки должен быть идентичным во всех ваших средах, включая среды разработки. Если разработчикам необходимо внести изменения в схему базы данных, они должны сделать это в локальной копии базы данных и обновить проект базы данных до фиксации своего кода.

Ответ №1:

Как упоминал Дэниел, использовать среды разработки без проекта базы данных — не очень хорошая идея. Однако бывают случаи, когда нам приходится работать в общей базе данных из-за цен на изолированную среду, тестовых данных или любых других ограничений. В этом случае слишком сложно проверить, готова ли ваша база данных разработчиков к синхронизации изменений, поскольку она может содержать необработанные изменения. Рассмотрите возможность использования процесса: ваши разработчики добавляют изменения в проект базы данных под управлением версиями. Они могут изменять базу данных разработчиков напрямую, но каждый разработчик передает в систему управления версиями только свою рабочую область. В этом случае вы можете увидеть изменения для каждой истории пользователя и ошибки в системе управления версиями и при необходимости связать их с соответствующими рабочими элементами. Кроме того, вы можете добавить базу данных интеграции для проверки согласованности новых изменений:

DEV (manually commit to SC) -> INT (pipelines CI/CD) -> TEST -> PROD

В качестве дополнительных идей:

  1. Вы можете попытаться создать закодированный тест пользовательского интерфейса или тест Selenim, чтобы нажимать кнопки на VS и обновлять свой проект базы данных. Затем вы можете добавить его в конвейер и обновлять свой SC каждую ночь.
  2. SqlPackage.exe генерирует сценарий обновления Database -> DacPac file . Однако нет никаких способов применить его к проекту базы данных.

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

1. Спасибо. Я согласен, что этой практики следует избегать, когда это возможно. В этом случае мы не можем диктовать, как команда разработчиков клиента выполняет свою работу в процессе разработки. Похоже, что нет автоматизации в отношении запуска сравнения схемы с проектом базы данных в качестве целевого объекта, так что это в значительной степени отвечает на вопрос. Ценю понимание. Я могу рассмотреть подход к кодированию пользовательского интерфейса, когда у меня будет больше времени.

Ответ №2:

Я согласен с Дэниелом, следует избегать запуска изменений базы данных непосредственно в базе данных разработчика. В этом случае вы могли бы попробовать использовать sql script в качестве примера:

 set nocount on;
-- Set the two variables newmodel and oldmodel to the appropriate database names and execute the script

declare @newmodel varchar(50), @oldmodel varchar(50);

Set @newmodel = '[NewModel to Compare]';
set @oldmodel = '[OldModel to Compare]';


Declare @Temp table (TABLE_SCHEMA varchar(40), TABLE_NAME varchar(40), COLUMN_NAME varchar(50), ORDINAL_POSITION int, IS_NULLABLE varchar(5), NullChange varchar(5), Comment varchar(50));

Declare @script varchar(5000);


set @script = '
Select nc.TABLE_SCHEMA, nc.TABLE_NAME, nc.COLUMN_NAME, nc.ORDINAL_POSITION, nc.IS_NULLABLE, IIF(nc.IS_NULLABLE <> oc.IS_NULLABLE, ''Yes'', ''No''), 
        IIF(oc.COLUMN_NAME IS NULL, convert(varchar(20), ''ADDED COLUMN''), convert(varchar(20), ''--'')) as Comment
    from {NEW}.INFORMATION_SCHEMA.COLUMNS nc
        LEFT join {OLD}.INFORMATION_SCHEMA.COLUMNS oc 
            on nc.TABLE_NAME = oc.TABLE_NAME and nc.COLUMN_NAME = oc.COLUMN_NAME
UNION ALL
    Select oc.TABLE_SCHEMA, oc.TABLE_NAME, oc.COLUMN_NAME, oc.ORDINAL_POSITION, oc.IS_NULLABLE, ''No'', ''DELETED COLUMN'' as Comment
    from {OLD}.INFORMATION_SCHEMA.COLUMNS oc
    where CONCAT(oc.TABLE_NAME, ''.'', oc.COLUMN_NAME) 
        not in (Select CONCAT(TABLE_NAME, ''.'', COLUMN_NAME) from {NEW}.INFORMATION_SCHEMA.COLUMNS)
';


Set @script = replace(@script, '{OLD}', @oldmodel);
Set @script = replace(@script, '{NEW}', @newmodel);

--print @script

Insert into @Temp
    exec(@script);

Select * from @Temp where Comment <> '--'
order by TABLE_NAME, ORDINAL_POSITION, COLUMN_NAME;
go