В Yii появились миграции

    Приятная новость для всех, кто использует или присматривается к PHP-фреймворку Yii. Готова ожидаемая многими возможность — миграции.

    Миграции очень важны для командной разработки, когда постоянно меняется не только код, но и структура базы данных. Чтобы каждый не применял руками изменения остальных членов команды и существуют миграции.

    Как происходит типичная работа с миграциями?

    Разработчик Андрей создаёт миграцию

    yiic migrate create --name=create_news_table

    Идёт в protected/migrations и наполняет её полезным кодом:

    class m20101129185401_create_news_table extends CDbMigration {
        public function up(){
            $this->createTable('tbl_news', array(
                'id' => 'pk',
                'title' => 'string NOT NULL',
                'content' => 'text',
            ));
        }
     
        /*
        public function down(){
        }
        */
    }
    


    Тут можно использовать совершенно любой код, например, зачистить кеш или assets.

    Далее Андрей как-то передаёт миграцию Ивану. Через SVN, почтой или по FTP — не важно (лучше, конечно, через систему контроля версий). Иван применяет миграцию:

    yiic migrate up

    и спокойно работает с новым кодом.

    Более подробное описание на русском будет на yiiframework.ru в ближайшее время (ну или, в крайнем случае, перед релизом).

    Миграции будут включены в следующий релиз Yii, а пока можно поиграться с trunk-ом. Синтаксис может незначительно поменяться до релиза.
    Support the author
    Share post

    Similar posts

    AdBlock has stolen the banner, but banners are not teeth — they will be back

    More
    Ads

    Comments 25

      0
      отлично, давно ждал этого функционала.
      пользовался до этого момента, этим расширением: www.yiiframework.com/extension/yii-dbmigrations
        0
        Будет очень полезно получить критики до релиза. Пока ещё можно всё переделать…
        0
        Что не нравится в таком подходе к миграциям — необходимость знания языка миграции $this->createTable('tbl_news', array(… каким бы простым он не был. И фактически невозможность изменения схемы при помощи любых других средств EMS и ему подобных.
        Оч нравится идея www.antonoff.info/development/mysql-migration-with-php-project Миграция создается ./migrate.php create и все. Т.е. фактически анализируются изменения в схеме бд и создаются необходимые SQL запросы.
        Т.е. например я создаю базу в mysql-workbench — это мне гораздо удобнее чем просто командами. Далее делаю ./migrate.php create. Это все что надо знать. Дальше все тоже самое.
        К сожаления пока не устраивает работа с FK, но повторюсь идея таких миграции мне кажется намного лучше.
          0
          Можно и SQL писать. Специальный синтаксис не обязателен.

          У Антонова интересная идея, но есть и минусы:
          — В такую автоматическую миграцию может попасть что-нибудь нежелательное.
          — Невозможно мигрировать, например, из MySQL в SQLite и обратно.
            0
            MySQLWorkbench сам прекрасно создает миграции.
              0
              А что конкретно не нравится в работе с FK?
              Может допилим совместными усилиями?
                0
                Работа с FK там уже поправлена
                0
                Протестировал — багов пока не обнаружил.

                Предложения:
                Можно реализовать хелперы как в ror, например для создания внешних ключей (в ror метод references) и timestamp полей.
                guides.rubyonrails.org/migrations.html

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

                хотя, по мне, если честно, мне в принципе хватает и текущего функционала.

                В любом случае, спасибо разработчикам!
                  0
                  Так там и так абстрагировано. Можно попробовать почитать в гайде на английском.
                    0
                    я имел ввиду создание/редактирование полей.
                    или я чего то не заметил?!
                    отписал в лс подробнее.
                  0
                  «Можно и SQL писать» — но это все равно неудобно :). С остальным согласен.
                  Сейчас невозможно работать, если есть FK, по крайнее мере, у меня миграции на достаточно большой базе создаются неправильно. Но тем не менее если бы работа была бы доведена до совершенства — это было удобнее. На счет миграции Mysql => SQLite… из моего опыта при миграции Mysql => Postgres на RoR (но как известно yii много идеи оттуда перенял) все равно многое приходилось допиливать, т.е. там еще хватит тоже гемороя.
                  В целом ничего против миграции не имею, миграции — это правильно и хорошо, а Yii вообще любимый фреймворк :). Но как информация к размышлению. Просто не люблю так работать на ранних стадиях развития проекта, когда база меняется постоянно :).
                    0
                    Немного оффтопа можно? В Yii всё ещё основной паттерн ORM ActiveRecord?
                      0
                      Да, модели основные AR.
                      0
                      ещё пару предложений:
                      1) можно добавить функционал для генерации полной схемы бд, при запуске миграций(опционально).
                      например: генерировать фаил с именем «номерМиграции_названияБазы.sql», а в нем полный дамп базы.

                      2) команду сделать, что то типа fullMigrate, которая зачистит всю бд и поднимет последнюю версию из миграций.
                        0
                        Хм… в ibatis migrations есть такая штука, хотя я не очень осознаю её пользу.
                          0
                          полный дамп нужен, что бы залить всю схему в бд разом (не выполнять же миграции поочереди, их может и тысячи оказаться).
                          а поднять полную схему может понадобиться как минимум в двух случаях:
                          1) при развертывание новой копии проекта.
                          2) восстановлении последний версии миграций: поковырялся я напрямую в бд, а потом захотел откатиться на актуальную версию…
                            0
                            1) Да, тут, в теории, может пригодиться.
                            2) А вот это противоречит идее миграций. Никаких рук.
                              0
                              противоречит, но не кто не запрещает, а простой способ откатиться хотелось бы иметь.
                        0
                        Не могу для себя решить, стоит ли пользоваться миграциями исключительно для переезда «локальный сервер»->development->production.

                        У нас для локальных серверов используется общая база, потому собственно и задумываюсь о целесообразности писать миграции.

                        *Можно и похоливарить на эту тему*
                          0
                          Определённо стоит. Иначе как узнать, кто и что менял?
                            0
                            Если кто-то меняет структуру БД, он же как правило и программирует ту часть функционала, которая отвечает за эти изменения.

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

                            Кроме того, если даже кто-то поменял что-то в БД и есть код, поддерживаемый другими членами команды, который может сломаться из-за этих изменений — об этом сразу скажут тесты.

                            Смысл миграций в моем понимании — обеспечение удобного механизма переноса изменений в БД, а не уведомление об этих изменениях. Но ведь я рассматриваю случай, когда база для локальных серверов разработчиков общая, соответственно ничего никуда переносить не нужно, не считая одноразовой операции переноса изменений на development и production сервер, которую проще и быстрее выполнить с помощью инструментов администрирования СУБД. Для уведомления достаточно словесного описания модификаций, что менее трудозатратно, чем писать миграции :) Или я не прав?

                              0
                              О, нет. В крупных проектах частенько одной частью занимается совсем не один человек. Сообщения из ICQ не доходят, не замечаются. Да человек вообще мог быть в отпуске…

                              С общей базой всё, конечно, проще, хотя тоже есть большая проблема: код ко всем попадает позже, чем изменения в базе. Соответственно у всех, кроме одного разработчика локальный проект может слечь на самом интересном месте.
                            0
                            Исключительно для этого переезда и пользуемся, правда локальная база у каждого своя. То есть схема работы примерно такая:
                            — ручками изменяю схему БД локально
                            — модифицирую код (коммиты в свою ветку svn)
                            — тестирую (если чужие модули валятся — связываюсь с тем, кто их делал, разбираемся вместе, если мелочь — правлю сам, если что-то крупное — он переключается на мою ветку)
                            — пишу/генерирую миграции
                            — сливаюсь со staging веткой, тестируюсь ещё раз
                            — коммичусь в staging
                            — автоматом идёт деплой на staging сервер и запускаются миграции

                            Получаем, что код и БД стэйджа синхронизированы всегда и соответствуют ветке в репе.

                            0
                            а как с транзакциями внутри одного действия миграции? есть?

                            понятно что можно разбить до самых мелких действий, но например иногда в цикле нужно что-то выполнить, и если на определенной итерации произойдет какая-то ошибка, то по-уму нужно откатить…
                              0
                              В миграциях используются те же средства для работы с базой, что и в остальном фреймворке. Разница только в том, что для миграций есть способ записать это немного более компактно. Соответственно завернуть в транзакцию можно как обычно:

                              $transaction = Yii::app()->db->beginTransaction();
                              try{
                                      ...
                              }
                              catch(Exception $e){
                                      return $transaction->rollback();
                              }
                              $transaction->commit();
                              

                            Only users with full accounts can post comments. Log in, please.