Pull to refresh

Версионирование структуры БД в MySQL: MySQL Migration with PHP

Reading time 3 min
Views 13K
Когда БД проекта вырастает за пределы трех-пяти таблиц, продолжая при этом постоянно изменяться, на свет рождаются неудобства обмена изменениями между разработчиками. Проблема стара как мир, но инструмента удовлетворяющего мои требования я в ноябре 2009го найти не сумел.

Мои требования к инструменту очень просты:
  • Как бы я не издевался над структурой данных в приложении, инструмент должен уметь изменить структуру в другой инсталляции приложения так, чтобы она была идентична моей.
  • System requirements: PHP и MySQL — не более того.
  • Бесплатность.
  • Открытость.




Похожие инструменты


Давайте рассмотрим существующие интрументы. Если я что-то недогуглил — отпишитесь в комментах — буду благодарен, добавлю в статью.
  • Ruby on Rails — Доп. зависимость от RoR. UPD: подробности в комментах.
  • Doctrine — насколько я понял — нужно сначала изменить schema.yml, затем сгенерировать миграцию
  • MySQL Migration Toolkit — требует установки Java (не разбирался)
  • MySQL Workbench — требует графической оболочки и нескольких кликов мышью, умеет генерить alter-скрипты, которые можно потом накатывать автоматически.
  • habrahabr.ru/blogs/php/63585 — статья про Phing.
  • code.google.com/p/mygrate — Python
  • code.google.com/p/mysql-php-migrations — умеет генерить пустые классы миграций, запросы в них вписываются руками
  • svn.limb-project.com/misc/migration — не удавалось запустить, параметры подключения к БД захардкожены во всех 3х или 4х скриптах. Как обстоят дела сейчас не знаю. Знаю, что велись работы в этом направлении. Korchasa! Прокомментируешь?
  • Платные инструменты


Рассмотрев все эти варианты я решил создать свой инструмент, который бы удовлетворил всем этим требованиям. На мои решения при сборке велосипеда написании инструмента более всего повлияли два проекта: code.google.com/p/mysql-php-migrations и svn.limb-project.com/misc/migration

Что мы умеем:

  • Работать только в CLI-режиме.
  • Создать инициализационную схему.
  • Проинициализировать БД.
  • Создать PHP-класс миграции, в который уже не надо писать запросы руками — там все есть!!!
  • Накатить миграции до определенной даты.
  • Откатить миграции до определенной даты (осторожно, вы можете потерять данные навсегда )
  • Показать список доступных миграций, пометив текущую.
  • Хранить данные о версионности БД в таблице с заданным пользователем именем.


Чего мы не умеем:

  1. Создавать ALTER-скриты — все хранится внутри классов.
  2. Накатывать дампы и ALTER-скрипты.
  3. Работать с PDO — нам требуется MySQLi.
  4. Бегать за пивом.


Что мы имеем?

Всего один конфиг-файл

config.ini
host=localhost
user=root
password=
db=mmpi_test
savedir=db ; каталог для хранения классов миграций
verbose=On
versiontable=db_version ; имя таблицы для хранения мета-данных о версионности


Небольшую библиотеку кода.

Всего один исполняемый файл: ./migration.php

Несколько команд:

  • help: Показать HELP
  • schema: Создать инициализационную схему.
  • init: Загрузить инициализационную схему (инсталлировать БД)
  • create: Создать новую миграцию
  • list: Показать список доступных миграций. Текущая помечена тремя ***
  • migrate: Произвести миграцию БД до указанного времени или до последней версии, если время не указано


Все просто. Можно поэксперементировать на тестовой базе и приступать к работе.

Системные требования:


  • PHP >= 5.3 with MySQLi
  • MySQL >=5.0 ( на четверке просто не пробовал )
  • Пользователь MySQL должен иметь права на создание базы.


Что нужно знать


Команда migrate работает с параметрами, которые распознаются функцией strtotime. Если параметры не заданы берется текущее время. Имя класса миграции, а так же переменная внутри него хранит timestamp своего создания. Пользователь MySQL должен иметь права на создание новой базы — инструмент использует это при генерации новой миграции и при накатывании/откатывании миграций, после работы скрипт удаляет временную БД.

Механизм работы


При создании миграции: Создается временная БД, в нее вливается schema.php ( там запросы инициализационной схемы), далее по очереди вливаются миграции до самой последней. Снимается массив-снэпшот каждой из баз, определяются различия, создается новый класс миграции. Если вам при апгрейде/даунгрейде нужны какие-либо манипуляции с данными — отредактируйте класс.
При применении миграции: читается список миграций, определятеся миграция до которой нужен апгрейд/даунгрейд последовательно выполняются все миграции от текущей до целевой.

Класс миграции: содержит два массива up и down, запросы из которых последовательно выполняются при применении данной миграции в соответствующем направлении.

Где взять?



hg clone bitbucket.org/idler/mmp

P. S. Ну тут надо бы написать, что это альфа-версия! Прошу за код пинать, но не до смерти. Багрепорты и фичреквесты приветствуются. У меня оно работает, но это не значит, что заработает у всех.

P. P. S. Подумываю о версии для SQLite.
Tags:
Hubs:
+29
Comments 51
Comments Comments 51

Articles