Повторное выполнение сценариев разработки баз данных - PullRequest
2 голосов
/ 08 сентября 2008

В нашей текущей среде разработки баз данных мы автоматизируем процессы сборки, проверяем весь код sql из сценариев базы данных svn create и применяем их к различным базам данных разработки / qa.

Это все хорошо, и это огромное улучшение по сравнению с тем, что мы делали в прошлом, но у нас есть проблема с повторным запуском скриптов. Очевидно, что это не проблема с некоторыми сценариями, такими как изменение процедур, потому что вы можете запускать их снова и снова без негативного влияния на систему. Прямо сейчас, чтобы добавить метаданные и выполнить операторы, такие как операторы создания / изменения таблицы, мы добавляем код, чтобы проверить и посмотреть, существуют ли объекты, и если они есть, не запускать их.

Наша проблема в том, что у нас действительно есть только один выстрел для запуска сценария, потому что после запуска сценария объекты находятся в среде, и система больше не будет запускать сценарий. Если что-то должно измениться после развертывания, у нас сложный процесс запуска сценариев обновления с использованием сценариев обновления и надежды на то, что все происходит в правильном порядке, и все PKs выстраиваются между средами (базы данных, скажем так , "особенный").

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

Ответы [ 6 ]

2 голосов
/ 08 сентября 2008

Мы решаем это - или, по крайней мере, схожую проблему с этим - следующим образом:

  1. Схема имеет номер версии - он представлен таблицей, в которой по одной строке на версию, а также номер версии содержит скучные вещи, такие как отметка даты / времени, когда эта версия появилась.
  2. Имея схему создания / изменения DDL, обернутую в код, который выполняет изменения для нас.

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

По нашему опыту (который не является репрезентативным), в большинстве случаев изменения схемы достаточно малы / быстры, чтобы их можно было безопасно выполнить в транзакции, что означает, что в случае неудачи мы получим откат, а db будет " безопасно »- хотя всегда рекомендуется делать резервные копии перед применением обновлений схемы, если это практически возможно.

Я развил это из неприятного болезненного опыта. Это не идеальная система (или оригинальная идея), но в результате работы таким образом мы имеем высокую степень уверенности в том, что если два экземпляра одной из наших баз данных с одинаковой версией, то схема для этих двух баз данных будет быть почти одинаковыми практически во всех отношениях, и что мы можем безопасно перенести любую базу данных в текущую схему для этого приложения без вредных последствий. (К сожалению, последнее не на 100% верно - всегда есть исключение - но оно не слишком далеко от истины!)

2 голосов
/ 08 сентября 2008

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

http://wiki.rubyonrails.org/rails/pages/UnderstandingMigrations

1 голос
/ 08 сентября 2008

Сохраняете ли вы ваши существующие данные в базе данных? Если нет, вы можете взглянуть на что-то похожее на то, что Мэтт упомянул для .NET под названием RikMigrations

http://www.rikware.com/RikMigrations.html

Я использую это в своих проектах для обновления базы данных на лету, отслеживая изменения. Кроме того, это упрощает перемещение схемы базы данных на разные серверы и т. Д.

0 голосов
/ 08 июля 2009

Мы пошли по пути «сбросить и воссоздать схему». У нас было несколько классов в нашем тестовом пакете JUnit, который параметризовал сценарии для создания всех объектов в схеме для разработчика, выполняющего код. Это позволило всем разработчикам совместно использовать одну тестовую базу данных, и каждый мог одновременно создавать / тестировать / удалять свои тестовые таблицы без конфликтов.

Это заняло много времени? Да. Сначала мы использовали метод настройки для этого, что означало, что таблицы отбрасывались / создавались для каждого теста, и это занимало слишком много времени. Затем мы создали TestSuite, который можно было запустить один раз перед всеми тестами для класса, а затем очистить после завершения всех тестов класса. Это все еще означало, что установка db выполнялась много раз, когда мы запускали наш класс AllTests, который включал все тесты во всех наших пакетах. Я решил, что это добавление семафора в код OracleTestSuite, поэтому, когда первый тест запрашивает настройку базы данных, он это делает, но любой последующий вызов просто увеличивает счетчик. Когда вызывался каждый метод tearDown (), счетчик уменьшал счетчик до тех пор, пока он не достигнет 0, а код OracleTestSuite отбросил бы все. Остается одна проблема: предполагают ли тесты, что база данных пуста. Может быть удобно сообщить тестам базы данных порядок, в котором они выполняются, чтобы они могли воспользоваться преимуществами состояния базы данных, поскольку это может уменьшить дублирование при настройке БД.

Мы использовали концепцию ObjectMothers для решения аналогичной проблемы с созданием сложных доменных объектов для целей тестирования. Ложные объекты могли бы быть лучшим ответом, но мы не слышали о них в то время. После всего этого времени я бы порекомендовал создать вспомогательные методы тестирования, которые могли бы создавать стандартизированные наборы данных для типичных сценариев. Кроме того, это поможет документировать важные крайние случаи с точки зрения данных.

0 голосов
/ 08 сентября 2008

Скотт назвал пару других инструментов SQL , которые решают проблему управления изменениями. Но я все еще катаюсь.

Я хотел бы повторить этот вопрос и добавить свое недоумение, что для этой проблемы еще нет бесплатного инструмента для сообщества. Очевидно, что сценарии не являются удовлетворительным способом поддержки схемы базы данных; ни один не случаи. Итак, почему мы не храним метаданные в отдельном (и в то же время независимом от платформы) формате?

Вот что я сейчас делаю. Моя основная схема базы данных - это управляемый версиями XML-файл, изначально созданный из простого веб-сервиса. Простая программа на JavaScript сравнивает экземпляры с ней, а простое XSL-преобразование дает операторы CREATE или ALTER. Он имеет ограничения, например RikMigrations ; например, он не всегда корректно упорядочивает взаимозависимые объекты. (Но угадайте, что - ни один из них не инструмент публикации баз данных Microsoft SQL Server .) На самом деле, это слишком просто. Я просто не включил объекты (роли, пользователей и т. Д.), Которые я не использовал.

Итак, я считаю, что эта проблема действительно решается неадекватно, и что рано или поздно нам придется собраться и заняться дьявольскими подробностями.

0 голосов
/ 08 сентября 2008

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

допустим, у вас есть таблица. Клиенты:

create table Customers (
   id int identity(1,1) primary key,
   first_name varchar(255) not null,
   last_name varchar(255) not null
)

и позже вы хотите добавить столбец статуса. Не изменяйте исходный табличный скрипт, который уже запущен (и может иметь синтаксис if (! Существующие), чтобы он не вызывал ошибок при повторном запуске).

Вместо этого есть новый скрипт с именем add_customer_status.sql

в этом скрипте у вас будет что-то вроде:

alter table Customers
add column status varchar(50) null

update Customers set status = 'Silver' where status is null

alter table Customers
alter column status varchar(50) not null

Опять же, вы можете заключить это в блок if (! Существующие), чтобы разрешить повторный запуск, но здесь мы использовали идею, что это скрипт изменения, и мы соответствующим образом адаптируем базу данных. Если в таблице клиентов уже есть данные, то все в порядке, поскольку мы добавляем столбец, заполняем его данными, а затем добавляем ограничение not null.

Обе упомянутые выше среды миграции хороши, у меня также был отличный опыт работы с MigratorDotNet .

...