Календарь на Май 2024 года: calendar2008.ru/2024/may/
Навигация
Главная »  Sql 

Миграция базы данных в Zend Framework: Akrabat_Db_Schema_Manager


Источник: habrahabr
3axap4eHko
В процессе работы над одним огромным проектом на Zend Framework, возникла необходимость миграции баз данных и перемещение между версиями, т.е. кроме update, был необходим так называемый downdate. Немного погуглив натолкнулся на интересную статью Роба Алана (в дальнейшем Автор) "Akrabat_Db_Schema_Manager: Zend Framework database migrations". Данная статья не является переводом оригинала, а скорее синтезом его и возникшей проблемы. Об этом и пойдет разговор.

После каждого изменения в базе данных (добавление столбцов, таблиц, индексов, ключей и т.д.), нужно создавать отдельный файл миграции. Подобные файлы можно размещать в каталоге ./scripts/migrations. Автор предлагает именовать файл миграции как 001-CreateUsersTable.php. Номер определяет порядок, в котором данные файлы будут запускаться, т.е. по сути идет [порядковый номер]-[краткое описание миграции].php. Но в этом не так много информативности. По этому мы решили именовать миграцию как[номер-ревизии]-[краткое описание миграции].php. Для тех кто пользуется hg могут использовать порядковый номер changeset. В связи с этим пришлось немного переписать класс Akrabat_Db_Schema_Manager, т.к. в одну ревизию могло входить несколько миграций и имена файлов переопределялись. Метод _getMigrationFiles() возвращает не массив вида:
$files["v$versionNumber"] = array( 'path'=>$path, 'filename'=>$entry, 'version'=>$versionNumber, 'classname'=>$className); А массив массивов: $files["v$versionNumber"][] = array( 'path'=>$path, 'filename'=>$entry, 'version'=>$versionNumber, 'classname'=>$className); 

Соответственно изменения коснулись и метода _processFile($migration, $direction), в который передавался параметр $migration не как массив, а массив массивов. Кому интересно, исходные коды классов выложу наGitHub, а пока расскажу про основной алгоритм модернизации. Файл миграции содержит класс наследуемый от Akrabat_Db_Schema_AbstractChange и содержащий два метода: up() и down(). Метод up() запускает процесс обновления БД, а down() - в случае отката ревизии. Вот немного измененный пример, который приводит Автор:
class CreateUsersTable extends Akrabat_Db_Schema_AbstractChange { function up() { $tableName = $this->_tablePrefix . 'users'; $sql = "CREATE TABLE IF NOT EXISTS $tableName ( id int(11) NOT NULL AUTO_INCREMENT, username varchar(50) NOT NULL, password varchar(75) NOT NULL, roles varchar(200) NOT NULL DEFAULT 'user', PRIMARY KEY (id) )"; $this->_db->query($sql); $data = array(); $data['username'] = 'admin'; $data['password'] = sha1('password'); $data['roles'] = 'user,admin'; $this->_db->insert('users', $data); }  function down() { $tableName = $this->_tablePrefix . 'users'; $sql = "DROP TABLE IF EXISTS $tableName"; $this->_db->query($sql); } } 

В примере введена поддержка префикса таблиц, который указывается в конфигурационном файле, в ключе resources.db.table_prefix. Но опять есть 1 минус, имя класса совпадает с [кратким описанием миграции], и если у нас будет хотя бы 2 одинаковых описания, то вылетит Fatal error: Cannot redeclare class. Для этого определим индекс массива 'classname' как
'classname'  => $className.$versionNumber

и аналогично именуем класс - это позволит избежать нам ошибки. 
А теперь - самое вкусное. Прикручиваем всю эту красоту к zend Tool. Как установить Zend Tool я рассказывать не буду, об этом уже много писали. Для начала определимся где хранить Akrabat ZF Library, я предпочитаю все PHP библиотеки хранить в /usr/share/php/, это значит что путь к ней будет /usr/share/php/Akrabat. Далее все просто:
$ zf --setup storage-directory $ zf --setup config-file $ echo "`php -r 'echo get_include_path().PATH_SEPARATOR;'`/usr/share/php/Akrabat">~/.zf.ini $ echo "basicloader.classes.0 = "Akrabat_Tool_DatabaseSchemaProvider"">>~/.zf.ini 

Теперь убедимся что все работает:
$ zf ? database-schema 

Должны увидеть что-то похожее:
Zend Framework Command Line Console Tool v1.11.11 Actions supported by provider "DatabaseSchema" DatabaseSchema zf update database-schema env[=development] dir[=./scripts/migrations] zf update-to database-schema version env[=development] dir[=./scripts/migrations] zf decrement database-schema versions[=1] env[=development] dir[=./scripts/migrations] zf increment database-schema versions[=1] env[=development] dir[=./scripts/migrations] zf current database-schema env[=development] dir[=./migrations] zf get-table-prefix database-schema 

Источники

  1. Статья Автора
  2. Akrabat ZF Library на GitHub.com


 

 Том Кайт: о разделении, расщеплении и удалении (On Sharing, Splitting, and Deleting, By Tom Kyte).
 Поиск курса валюты. SQL-запрос в Oracle..
 Аналитические функции в Oracle (Часть 1).
 Защита на уровне строк - Часть 2: Правила защиты.
 Что возвращать - массивы данных или результирующие множества?.


Главная »  Sql 

© 2024 Team.Furia.Ru.
Частичное копирование материалов разрешено.