После нескольких итераций выбранный нами подход был примерно таким:
Один файл на таблицу и хранимую процедуру. Также отдельные файлы для других вещей, таких как настройка пользователей базы данных, заполнение справочных таблиц их данными.
Файл для таблицы начинается с команды CREATE и последовательности команд ALTER, добавляемых по мере развития схемы. Каждая из этих команд заключена в скобки в тестах на предмет того, существует ли таблица или столбец. Это означает, что каждый скрипт может быть запущен в современной базе данных и ничего не изменит. Это также означает, что для любой старой базы данных скрипт обновляет ее до последней схемы. А для пустой базы данных сценарий CREATE создает таблицу, а сценарии ALTER все пропускаются.
У нас также есть программа (написанная на Python), которая сканирует каталог, полный сценариев, и собирает их в один большой сценарий. Он анализирует SQL только для того, чтобы вывести зависимости между таблицами (на основе ссылок на внешние ключи) и упорядочить их соответствующим образом. В результате получается монстр-SQL-скрипт, который за один раз приводит базу данных в соответствие со спецификацией. Программа сборки сценариев также вычисляет хэш MD5 входных файлов и использует его для обновления номера версии, записанного в специальную таблицу в последнем сценарии в списке.
За исключением несчастных случаев, в результате сценарий базы данных для заданной версии исходного кода создает схему, с которой этот код был разработан для взаимодействия. Это также означает, что существует один (несколько большой) сценарий SQL, который можно предоставить клиенту для создания новых баз данных или обновления существующих. (Это было важно в этом случае, потому что было бы много экземпляров базы данных, по одному для каждого из их клиентов.)