Делаем oracle deploy-скрипт независимым от окружения

в 9:28, , рубрики: deploy, oracle, standards, Администрирование баз данных, метки: , ,

Уже не одна правильная статья написана про необходимость и преимущества хранения исходных кодов схем базы данных в системах контроля версий (типа CVS, SVN, TFS и др.), а также ведения deploy – скриптов.
Не стану повторяться, но разберем один специфических аспектов этого процесса.

Не секрет, что нормально поставленный процесс разработки состоит из собственно разработки(Dev), внутреннего тестирования(QA), приёмочного тестирования конечными пользователями (UAT) и, непосредственно, «Production». Детали жизненного цикла могут отличаться в индивидуальных случаях, но это не существенно для темы статьи.

Порой (а в опыте автора – часто) так случается, что окружения, на которых происходят разные этапы этого цикла могут отличаться по тем или иным причинам. Различия могут быть какие угодно. От разных tablespace-ов, до отличий в названиях схем, DBLink-ов и других индивидуальных особенностей. Как эффективно решить эту неприятность мы и рассмотрим в этой статье.

image

Рядом с основным deploy.sql-скриптом (который вызывает другие скрипты с непосредственно исходниками объектов базы), кладём папочку, в которой хранился бы набор файлов под каждую среду с набором индивидуальных параметров — define-ов.

	DEFINE DATA_TS = DEV_DATA_TS
	DEFINE INDEX_TS = DEV_DATA_TS
	DEFINE Some_Source_data_dbl = Dev_dbl_source.world
	-- ... и т.д.
	

Для каждого окружения он будет свой.
Далее в исходных текстах вашей базы, остаётся только использовать переменные подставновки, например:

	create table my_table (sample_col VarChar(2 char) ) tablespace &DATA_TS;
	.... 
	select * from dual@&Some_Source_data_dbl;
	

Таким образом ваши скрипты будут индифферентны к окружению, и вы с большей уверенностью сможете сказать, что отработав на тестовом окружении, они так же надёжно отработают и на UAT(например). В итоге, вы не меняете сами исходные коды под каждое конкретное окружение, тем самым убирая риск человеческого фактора: опечатки, забывчивости, вероятность отвлектись.
Риски того, ошибка проберется в сам файла параметров-подстановок уходит уже после 1-2-3 итераций сбора окружения (да и вычитать файл подстановок, как правило, не так уж сложно).

Осталось только корректно вызвать все эти скрипты в нужном порядке и с минимальной головной болью для дальнейшей поддержки. Тут вступает, на первый взгляд, небольшой вопрос: как назвать эти файлы с настройками. Раньше мы их называли подобным образом:

dev.sql
qa.sql
uat.sql
prod.sql

Но сейчас отказались от такой практики, и называем по TNS-имени среды.
Что это даёт? У нас есть .sh скрипт подобного вида (оставляю только суть):

	# ... здесь заголовки отвечающие за ключи, help, реакцию на отсутствие параметров итд
	par_file = ${3//.WORLD/}
	sqlplus $1/$2@$3 @deploy.sql $par_file
	# ... здесь отработка выхода с ошибкой
	

На вход скрипта (в данном упрощённом варианте, когда у вас только одна схема) приходит три параметра: логин, пароль и TNS-алиас. Учитывая что многие прописывают

names.default_domain = world

то приводим всё к единому формату (в нашем случае: отрезаем потенциально появившийся ".WORLD"). В итоге остается наше имя файла параметров (по названию TNSalias) которое надо будет вызвать.

Остается для полноты картины написать пример самого deploy.sql

	-- Создаём лог файл 
	spool _deploy.log
	-- запускаем набор подстановок на основании переданного 
	-- нам par_file в первом парамере вызова:
	@./defines/&1

	@../ddl/some_table_create.sql
	@../data/some_other_deploy_activity.sql

	@./validate_invalid_objects.sql
	@./run_post_deployment_checks.sql

	spool off
	exit
	

Вводя подобный стандарт в ваш процесс разработки вы со временем раз и навсегда забываете о разнице в ваших окружениях, что поверьте мне, сильно уменьшает «головную боль» в последний момент — в момент deployment-а.

PS: Хотелось бы поделиться с хабросообществом некоторыми навыками и best-practices, приобретенными мною за годы работы с базами данных. Хотелось бы открыть цикл коротких статей основанный на примерах c разборами тех или иных интересных, на мой взгляд, случаев, задач и подводных камней с которыми мне приходилось сталкиваться.

Автор: DenKrep

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js