Как стать автором
Обновить
2
0
Алексей Штокало @ashtokalo

Пользователь

Отправить сообщение
Крым так же накрыло. Нашим разработчикам заблокировали доступ к репозитариям компании, остался только доступ к личным. VPN помогает только с новым аккаунтом. Видимо нужно разворачивать всё у себя, как это было раньше.
Тут нечего показывать. В проекте только MySQL. Родной дамп оказался быстрее и проще. Для схемы используется банальный mysqldump:
mysqldump --add-drop-table --no-data --routines $DBNAME > $SCHEMA
Аналогично для выборки данных из нужных таблиц. Данные из таблиц храним в отдельных файлах, так с ними удобнее работать.

Импорт чуть более сложен, но только из-за добавленой интерактивности. Схема разбивается на части и выполняется по частям. Это позволяет видеть процесс по каждой таблице и сразу загружать её данные. Данные так же грузим частями, чтобы был виден прогресс и чтобы не спотыкаться на размере буфера. У нас в схеме больше сотни таблиц, некоторые словари имеют десятки тысяч записей и занимают несколько мегабайт. Без такой разбивки процесс импорта весьма скучен :)

Пример кода для импорта, чтобы было чуть более понятно
// search for all tables in the schema
if (preg_match_all('%\s*DROP\s+TABLE\s+(?:IF\s+EXISTS\s+)?(?#
	  )\`([a-z_A-Z]+)\`.+(?=DROP\s+TABLE|\/\*\!\d+\s+DROP\s+FUNCTION(?#
	  )|\/\*\!\d+\s+DROP\s+PROCEDURE)%sU', $sSchema, $aMatches))
{
	$sSql = '';
	foreach ($aMatches[1] as $i => $sTable)
	{
		$this->write(sprintf('    > create table %s ...', $sTable));

		$sSql = $aMatches[0][$i];

		// apply global settings from sql dump header
		if ($i === 0)
		{
			$sSql = substr($sSchema, 0, strpos($sSchema, $sSql)) 
				. $sSql;
		}

		$iTime = microtime(true);

		// clear auto increment value
		$sSql = preg_replace('/AUTO_INCREMENT=\d+/', '', $sSql);

		Yii::app()->db->createCommand($sSql)->execute();

		$this->write(sprintf(' done (time: %.3fs)' . PHP_EOL,
			microtime(true) - $iTime));
			
		$this->loadTableData($sTable);
	}

	// leave only routines in schema
	$sSchema = substr($sSchema, strpos($sSchema, $sSql) +
		strlen($sSql));
}

// and then routines
if (preg_match_all('%(?:/\*!\d+\s+)?DROP\s+(FUNCTION|PROCEDURE)\s+(?#
	  )(?:IF\s+EXISTS\s+)?`([a-z_A-Z]+)`.+\sDELIMITER\s\;\;(.+)\;\;(?#
	  )\s+DELIMITER\s\;\s%Ums', $sSchema, $aMatches))
{
	foreach ($aMatches[2] as $i => $sName)
	{
		$this->write(sprintf('    > create %s %s ...',
			strtolower($aMatches[1][$i]), $sName));

		$sDropSql = preg_replace('/;.+$/Ss', '', $aMatches[0][$i]);

		$iTime = microtime(true);

		// drop function or procedure if exists
		Yii::app()->db->createCommand($sDropSql)->execute();

		Yii::app()->db->createCommand($aMatches[3][$i])->execute();

		$this->write(sprintf(' done (time: %.3fs)' . PHP_EOL,
			microtime(true) - $iTime));
	}
}

У нас для этого есть две консольные команды, условно export и import. Соотвественно, первая — умеет делать дамп схемы, хранимых процедур и данных из заранее указанных таблиц — словари, миграции и т.п. Вторая команда умеет создавать базу из такого дампа и загружать данные в нужные таблицы. Собранные дампы добавлены в систему контроля версий. При создании новой миграции, после её применения, мы запускаем первую команду. Это обновляет дампы и даёт возможность отслеживать изменения с помощью системы контроля версий, без анализа самих миграций. Эти команды так же используются для разворачивания проекта и автоматического тестирования. Что позволяет избегать запуска сотен миграций. Всё это замечательно работает на базе Yii уже много лет.

Информация

В рейтинге
Не участвует
Откуда
Краснодарский край, Россия
Зарегистрирован
Активность