Дампим БД
Александр СкакуновОпубликовано 5.12.2007 в Статьи
Поработав с фреймворком Symfony, я открыл для себя такую интересную вещь, как фикстуры (fixtures). Это тот минимальный набор дефолтных данных, которые должны присутствовать в базе сразу после создания билда проекта. Практически в любом проекте надо с ходу иметь какие-то дефолты:
- настройки
- список стран, языков, валют
- каких-то дефолтовых пользователей
- локализованные тексты
Так вот фикстуры содержат эти данные.
Вне рабочих стен я не использую Symfony, но идея запала в душу. Вот как я ее решил на своем обычном окружении.
Выдрать данные из таблицы MySQL просто: для этого есть тулза mysqldump. Однако дампить все подряд не очень здорово – так в билд попадут всякие девелоперские данные, которые чаще всего представляют собой маты разных языков и строку “qwerty”
Поэтому дампить имеет смысл в два присеста:
- Структура БД (DDL)
- Данные избранных таблиц (DML)
Для этого был написан небольшой batch-файл, который делает все это для меня.
@SET DATABASE=my_project_dev
@SET DUMP_FILE=dump.sql
@SET COMMON_PARAMS=--default-character-set=utf8 -uuser -ppass --disable-keys --quote-names
@rem Define list of tables to load their data (not only metadata), space separated
@SET TABLES=countries languages currencies settings fuseactions
@rem DDL. "--databases" is added to make mysqldump add CREATE DATABASE + USE statements
mysqldump --no-defaults --no-create-info=false --no-data=true --add-drop-table %COMMON_PARAMS% --databases %DATABASE% > %DUMP_FILE%
@rem DML
mysqldump --no-create-info=true --no-data=false --extended-insert %COMMON_PARAMS% %DATABASE% %TABLES% >> %DUMP_FILE%
В первой части задается имя базы, с которой мы имеем дело, а также имя выходного файла.
Затем задаются параметры mysqldump, общие для обоих шагов.
После этого идет список таблиц, из которых нам нужно получить фикстуры.
И уже после этого в два присеста дампим DDL проекта и DML-фикстуры.
Файл, полученный в результате этого опыта, я коммичу в репозиторий своего проекта, так что скрипт сборки билда использует этот файл для создания БД. Таким образом очень здорово отслеживаются изменения в структуре базы.
P.S. Да, batch-файл я запускаю ручками перед каждым коммитом, если имело место изменение в БД – если кто подскажет, как сделать это автомагически, буду только рад. Юзаю Tortoise SVN.
Понравилась статья? Подпишись на обновления по RSS/E-mail


Ага, в Джанге тоже такое есть. http://www.djangoproject.com/documentation/django-admin/#loaddata-fixture-fixture
Их можно еще в XML и JSON сохранять.
Полностью согласен )
Да, такой подход я тоже давно использовал и он себя хорошо зарекомендовал, правда не знал, что называется это “фикстурами”, теперь буду знать.
Самое важное в нем – это соблюдение принципа, в соответствии с которым значительную часть проекта можно собрать из текстовых файлов. Знаю ситуации, когда в систему контроля версий вносят бинарную БД – это, конечно, не годится.
Что касается автоматизированного вызова пакетного файла перед коммитом, думаю, что лучше сделать не так, а включить его вызов в процедуру сборки проекта. Тогда при каждой сборке проекта автоматически будут свежие фикстуры. Иначе, например, проект можно не коммитить, а скопировать куда-нибудь, а фикстуры останутся необновленными.
Немного добавлю, что фикстуры не ограничиваюся набором тестовых/default-овых данных.
Это может быть код, который инициализаирует тестовое окружение или эмулирует некий набор действий, для организации автоматического тестирования.
Насчет обновления структуры БД в файле перед коммитом – процедуру так и не удалось автоматизировать, потому сделал достаточно банально – поставил запуск скрипт на cron
да, удобная штука и необходимая для тестов, но для симфони конечно это велосипед (или баян):)
php symfony propel-dump-data
php symfony propel-load-data []
2 Andrey: ну так я ж идею только взял из Симфони. Понятное дело, что там “все украдено до нас”.
Тем более, Симфони фикстуры в Yaml-формате, а не в SQL, что гораздо более читабельно.
а, тогда сорри, тем более шо батник я се сохранил)
На здоровье
Вот если б кто-нить запостил пример кашерного one-step-build скрипта… А то свой домо-рощенный мне стыдно показывать
Кстати, на каком-то этапе таблицы не хотели создаваться, т.к. InnoDB не пропускал проблемные форейн-кеи. Потом решилось тем, что в дампе появилась такая строчка (их там много таких интересных):
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
Мне кажется, изначально все стартовые данные стоит как раз в фикстуры и записывать ручками, а не из базы дампить. Это идеологически.
Когда-то сам пользовался таким подходом, только делал ANT-таски (то же самое что и pake task в Symfony) специально для этого…
п.с. зачем делать “доморощенные” скрипты в виде bat-файлов, если существуют готовые инструменты для билдов, которые можно дорабатывать?
Это от дремучести. Научи.
Посмотрел я Symfony…пока питонисты поглядывают свысока на пхп у вас такие классные фреймворки появились!
Плюсов много. Минусы тоже есть
Скакунов Александр, есть классический ANT джавовский, у которого есть плагины для работы с SQL, с архивами и.т.д., на нем даже build/deploy тулзу сделать можно. Советую посмотреть его.
Есть его аналог (но функционал послабее) на PHP — Phing, если я не ошибаюсь, то в symfony всякие pake-таски именно через этот phing и запускаются.
Макс Ищенко, Symfony в настоящий момент не менее сырой чем тот же Pylons, например, не хватает всяких адаптеров между слоями, потому смена одного ORM’а на другой означает прекращение работы кучи плагинов
Александр Локшин – спасибо, буду копать. Может статью напишешь?
Скакунов Александр, а что, надо подумать
Поигравшись с методом, описанным в статье, я понял, что это не совсем фикстуры, и в Симфони с этим удобнее.
Например, для нормальной работы приложения в БД в таблице с юезрами д.б. хотя бы один юзер – ни первый, ни второй шаг дампа не помогут, т.к. таблица будет либо пустая, либо включать всякий хлам, который девелопер имел честь насоздовать во время разработки. Нормальной фикстурой была бы вставка в пустую таблицу требуемых исходных данных (скажем, одного эталонного юзера).
Думаю как сделать…