Spec-Zone.ru › Yii 2.0

Миграция базы данных

  1. Создание миграций
  2. Генерация миграций
  3. Применение миграций
  4. Отмена миграций
  5. Повторное применение миграций
  6. Просмотр миграций
  7. Изменение истории миграций
  8. Настройка миграций
  9. Миграция нескольких баз данных

В процессе разработки и поддержки приложения, использующего базу данных, структура используемой базы данных эволюционирует, подобно коду. Например, в ходе разработки может потребоваться новая таблица; после развертывания приложения в производство может оказаться необходимым создать индекс для повышения производительности запросов и так далее. Поскольку изменение структуры базы данных часто требует изменений в коде, Yii поддерживает возможность миграции базы данных, которая позволяет отслеживать изменения в базе данных в виде миграций, которые контролируются вместе с исходным кодом.

Следующие шаги показывают, как команда может использовать миграции базы данных в процессе разработки:

  1. Тим создаёт новую миграцию (например, создаёт новую таблицу, изменяет определение столбца и т. д.).
  2. Тим коммитит новую миграцию в систему контроля версий (например, Git, Mercurial).
  3. Даг обновляет свой репозиторий из системы контроля версий и получает новую миграцию.
  4. Даг применяет миграцию к своей локальной базе данных разработки, тем самым синхронизируя свою базу данных с изменениями, внесёнными Тимом.

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

  1. Скотт создаёт метку выпуска для репозитория проекта, содержащую новые миграции базы данных.
  2. Скотт обновляет исходный код на сервере производства до метки выпуска.
  3. Скотт применяет накопленные миграции базы данных к базе данных производства.

Yii предоставляет набор командной строки для миграций, которые позволяют:

  • создавать новые миграции;
  • применять миграции;
  • отменять миграции;
  • повторно применять миграции;
  • отображать историю и статус миграций.

Все эти инструменты доступны через команду yii migrate. В этом разделе мы подробно опишем, как выполнить различные задачи с помощью этих инструментов. Вы также можете получить информацию о каждом инструменте, используя команду помощи yii help migrate.

Подсказка: миграции могут влиять не только на схему базы данных, но и корректировать существующие данные для соответствия новой схеме, создавать иерархию RBAC или очищать кэш.

Создание миграций

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

yii migrate/create <name>

Необходимый name аргумент даёт краткое описание новой миграции. Например, если миграция связана с созданием новой таблицы с именем news, вы можете использовать имя create_news_table и выполнить следующую команду:

yii migrate/create create_news_table

Примечание: поскольку аргумент name будет использоваться как часть имени сгенерированного класса миграции, он должен содержать только буквы, цифры и/или символ нижнего подчеркивания.

Вышеуказанная команда создаст новый файл PHP-класса с именем m150101_185401_create_news_table.php в каталоге @app/migrations. Файл содержит следующий код, который в основном объявляет класс миграции m150101_185401_create_news_table со скелетным кодом:

<?php

use yii\db\Migration;

class m150101_185401_create_news_table extends Migration
{
    public function up()
    {

    }

    public function down()
    {
        echo "m101129_185401_create_news_table cannot be reverted.\n";

        return false;
    }

    /*
    // Use safeUp/safeDown to run migration code within a transaction
    public function safeUp()
    {
    }

    public function safeDown()
    {
    }
    */
}

Каждая миграция базы данных определена как PHP-класс, наследуемый от yii\db\Migration. Имя класса миграции автоматически генерируется в формате m<YYMMDD_HHMMSS>_<Name>, где

  • <YYMMDD_HHMMSS> относится к дате и времени UTC, в котором выполняется команда создания миграции.
  • <Name> совпадает со значением аргумента name, который вы предоставляете команде.

В классе миграции ожидается, что вы напишете код в методе up(), который вносит изменения в структуру базы данных. Возможно, вы также захотите написать код в методе down(), чтобы отменить изменения, внесённые методом up(). Метод up() вызывается при обновлении базы данных с помощью этой миграции, а метод down() вызывается при понижении версии базы данных. Следующий код показывает, как вы можете реализовать класс миграции для создания таблицы news:

<?php

use yii\db\Schema;
use yii\db\Migration;

class m150101_185401_create_news_table extends Migration
{
    public function up()
    {
        $this->createTable('news', [
            'id' => Schema::TYPE_PK,
            'title' => Schema::TYPE_STRING . ' NOT NULL',
            'content' => Schema::TYPE_TEXT,
        ]);
    }

    public function down()
    {
        $this->dropTable('news');
    }
}

Информация: не все миграции обратимы. Например, если метод up() удаляет строку таблицы, вы, возможно, не сможете восстановить эту строку в методе down(). Иногда вы можете просто не захотеть реализовывать метод down(), поскольку обращение миграций базы данных не очень распространено. В этом случае вы должны вернуть значение false в методе down(), чтобы указать, что миграция необратима.

Базовый класс миграции yii\db\Migration предоставляет подключение к базе данных через свойство db. Вы можете использовать его для управления схемой базы данных с помощью методов, описанных в Работа со схемой базы данных.

Вместо использования физических типов при создании таблицы или столбца вы должны использовать абстрактные типы, чтобы ваши миграции были независимы от конкретной СУБД. Класс yii\db\Schema определяет набор констант для представления поддерживаемых абстрактных типов. Эти константы имеют имя в формате TYPE_<Name>. Например, TYPE_PK относится к типу первичного ключа с автоинкрементом; TYPE_STRING относится к строковому типу. Когда миграция применяется к конкретной базе данных, абстрактные типы будут переведены в соответствующие физические типы. В случае MySQL, TYPE_PK будет преобразовано в int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY, а TYPE_STRING станет varchar(255).

Вы можете добавить дополнительные ограничения при использовании абстрактных типов. В приведенном выше примере NOT NULL добавляется к Schema::TYPE_STRING, чтобы указать, что столбец не может быть null.

Информация: соответствие между абстрактными и физическими типами задается свойством $typeMap в каждом конкретном классе QueryBuilder.

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

<?php

use yii\db\Migration;

class m150101_185401_create_news_table extends Migration
{
    public function up()
    {
        $this->createTable('news', [
            'id' => $this->primaryKey(),
            'title' => $this->string()->notNull(),
            'content' => $this->text(),
        ]);
    }

    public function down()
    {
        $this->dropTable('news');
    }
}

Список всех доступных методов для определения типов столбцов доступен в документации API yii\db\SchemaBuilderTrait.

Генерация миграций

Начиная с версии 2.0.7, консоль миграций предоставляет удобный способ создания миграций.

Если имя миграции имеет специальную форму, например, create_xxx_table или drop_xxx_table, то сгенерированный файл миграции будет содержать дополнительный код, в данном случае для создания/удаления таблиц. В дальнейшем будут описаны все варианты этой функции.

Создание таблицы

yii migrate/create create_post_table

генерирует

/**
 * Handles the creation for table `post`.
 */
class m150811_220037_create_post_table extends Migration
{
    /**
     * @inheritdoc
     */
    public function up()
    {
        $this->createTable('post', [
            'id' => $this->primaryKey()
        ]);
    }

    /**
     * @inheritdoc
     */
    public function down()
    {
        $this->dropTable('post');
    }
}

Чтобы сразу создать поля таблицы, укажите их через опцию --fields.

yii migrate/create create_post_table --fields="title:string,body:text"

генерирует

/**
 * Handles the creation for table `post`.
 */
class m150811_220037_create_post_table extends Migration
{
    /**
     * @inheritdoc
     */
    public function up()
    {
        $this->createTable('post', [
            'id' => $this->primaryKey(),
            'title' => $this->string(),
            'body' => $this->text(),
        ]);
    }

    /**
     * @inheritdoc
     */
    public function down()
    {
        $this->dropTable('post');
    }
}

Вы можете указать дополнительные параметры полей.

yii migrate/create create_post_table --fields="title:string(12):notNull:unique,body:text"

генерирует

/**
 * Handles the creation for table `post`.
 */
class m150811_220037_create_post_table extends Migration
{
    /**
     * @inheritdoc
     */
    public function up()
    {
        $this->createTable('post', [
            'id' => $this->primaryKey(),
            'title' => $this->string(12)->notNull()->unique(),
            'body' => $this->text()
        ]);
    }

    /**
     * @inheritdoc
     */
    public function down()
    {
        $this->dropTable('post');
    }
}

Примечание: первичный ключ добавляется автоматически и по умолчанию называется id. Если вы хотите использовать другое имя, вы можете указать его явно, как --fields="name:primaryKey".

Внешние ключи

Начиная с версии 2.0.8, генератор поддерживает внешние ключи с помощью ключевого слова foreignKey.

yii migrate/create create_post_table --fields="author_id:integer:notNull:foreignKey(user),category_id:integer:defaultValue(1):foreignKey,title:string,body:text"

генерирует

/**
 * Handles the creation for table `post`.
 * Has foreign keys to the tables:
 *
 * - `user`
 * - `category`
 */
class m160328_040430_create_post_table extends Migration
{
    /**
     * @inheritdoc
     */
    public function up()
    {
        $this->createTable('post', [
            'id' => $this->primaryKey(),
            'author_id' => $this->integer()->notNull(),
            'category_id' => $this->integer()->defaultValue(1),
            'title' => $this->string(),
            'body' => $this->text(),
        ]);

        // creates index for column `author_id`
        $this->createIndex(
            'idx-post-author_id',
            'post',
            'author_id'
        );

        // add foreign key for table `user`
        $this->addForeignKey(
            'fk-post-author_id',
            'post',
            'author_id',
            'user',
            'id',
            'CASCADE'
        );

        // creates index for column `category_id`
        $this->createIndex(
            'idx-post-category_id',
            'post',
            'category_id'
        );

        // add foreign key for table `category`
        $this->addForeignKey(
            'fk-post-category_id',
            'post',
            'category_id',
            'category',
            'id',
            'CASCADE'
        );
    }

    /**
     * @inheritdoc
     */
    public function down()
    {
        // drops foreign key for table `user`
        $this->dropForeignKey(
            'fk-post-author_id',
            'post'
        );

        // drops index for column `author_id`
        $this->dropIndex(
            'idx-post-author_id',
            'post'
        );

        // drops foreign key for table `category`
        $this->dropForeignKey(
            'fk-post-category_id',
            'post'
        );

        // drops index for column `category_id`
        $this->dropIndex(
            'idx-post-category_id',
            'post'
        );

        $this->dropTable('post');
    }
}

Положение ключевого слова foreignKey в описании столбца не изменяет сгенерированный код. Это означает:

  • author_id:integer:notNull:foreignKey(user)
  • author_id:integer:foreignKey(user):notNull
  • author_id:foreignKey(user):integer:notNull

Все они генерируют один и тот же код.

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

В приведенном выше примере author_id:integer:notNull:foreignKey(user) сгенерирует столбец с именем author_id с внешним ключом к таблице user, а category_id:integer:defaultValue(1):foreignKey сгенерирует столбец category_id с внешним ключом к таблице category.

Начиная с версии 2.0.11, ключевое слово foreignKey принимает второй параметр, отделённый пробелом. Он принимает имя связанного столбца для сгенерированного внешнего ключа. Если второй параметр не указан, имя столбца будет извлечено из схемы таблицы. Если схема не существует, первичный ключ не задан или является составным, будет использоваться имя по умолчанию id.

Удаление таблицы

yii migrate/create drop_post_table --fields="title:string(12):notNull:unique,body:text"

генерирует

class m150811_220037_drop_post_table extends Migration
{
    public function up()
    {
        $this->dropTable('post');
    }

    public function down()
    {
        $this->createTable('post', [
            'id' => $this->primaryKey(),
            'title' => $this->string(12)->notNull()->unique(),
            'body' => $this->text()
        ]);
    }
}

Добавление столбца

Если имя миграции имеет форму add_xxx_column_to_yyy_table, то содержимое файла будет содержать операторы addColumn и dropColumn, необходимые для добавления столбца.

Для добавления столбца:

yii migrate/create add_position_column_to_post_table --fields="position:integer"

генерирует

class m150811_220037_add_position_column_to_post_table extends Migration
{
    public function up()
    {
        $this->addColumn('post', 'position', $this->integer());
    }

    public function down()
    {
        $this->dropColumn('post', 'position');
    }
}

Вы можете указать несколько столбцов следующим образом:

yii migrate/create add_xxx_column_yyy_column_to_zzz_table --fields="xxx:integer,yyy:text"

Удаление столбца

Если имя миграции имеет форму drop_xxx_column_from_yyy_table, то содержимое файла будет содержать операторы addColumn и dropColumn, необходимые для удаления столбца.

yii migrate/create drop_position_column_from_post_table --fields="position:integer"

генерирует

class m150811_220037_drop_position_column_from_post_table extends Migration
{
    public function up()
    {
        $this->dropColumn('post', 'position');
    }

    public function down()
    {
        $this->addColumn('post', 'position', $this->integer());
    }
}

Добавление таблицы соединения

Если имя миграции имеет форму create_junction_table_for_xxx_and_yyy_tables или create_junction_xxx_and_yyy_tables, то будет сгенерирован код, необходимый для создания таблицы соединения.

yii migrate/create create_junction_table_for_post_and_tag_tables --fields="created_at:dateTime"

генерирует

/**
 * Handles the creation for table `post_tag`.
 * Has foreign keys to the tables:
 *
 * - `post`
 * - `tag`
 */
class m160328_041642_create_junction_table_for_post_and_tag_tables extends Migration
{
    /**
     * @inheritdoc
     */
    public function up()
    {
        $this->createTable('post_tag', [
            'post_id' => $this->integer(),
            'tag_id' => $this->integer(),
            'created_at' => $this->dateTime(),
            'PRIMARY KEY(post_id, tag_id)',
        ]);

        // creates index for column `post_id`
        $this->createIndex(
            'idx-post_tag-post_id',
            'post_tag',
            'post_id'
        );

        // add foreign key for table `post`
        $this->addForeignKey(
            'fk-post_tag-post_id',
            'post_tag',
            'post_id',
            'post',
            'id',
            'CASCADE'
        );

        // creates index for column `tag_id`
        $this->createIndex(
            'idx-post_tag-tag_id',
            'post_tag',
            'tag_id'
        );

        // add foreign key for table `tag`
        $this->addForeignKey(
            'fk-post_tag-tag_id',
            'post_tag',
            'tag_id',
            'tag',
            'id',
            'CASCADE'
        );
    }

    /**
     * @inheritdoc
     */
    public function down()
    {
        // drops foreign key for table `post`
        $this->dropForeignKey(
            'fk-post_tag-post_id',
            'post_tag'
        );

        // drops index for column `post_id`
        $this->dropIndex(
            'idx-post_tag-post_id',
            'post_tag'
        );

        // drops foreign key for table `tag`
        $this->dropForeignKey(
            'fk-post_tag-tag_id',
            'post_tag'
        );

        // drops index for column `tag_id`
        $this->dropIndex(
            'idx-post_tag-tag_id',
            'post_tag'
        );

        $this->dropTable('post_tag');
    }
}

Начиная с версии 2.0.11, имена столбцов внешних ключей для таблиц соединения извлекаются из схемы таблицы. В случае, если таблица не определена в схеме, первичный ключ не задан или является составным, используется имя по умолчанию id.

Транзакционные миграции

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

Более простой способ реализации транзакционных миграций — поместить код миграции в методы safeUp() и safeDown(). Эти два метода отличаются от методов up() и down() тем, что они неявно заключены в транзакцию. В результате, если какая-либо операция в этих методах завершится ошибкой, все предыдущие операции будут автоматически отменены.

В следующем примере, помимо создания таблицы news, мы также вставляем начальную строку в эту таблицу.

<?php

use yii\db\Migration;

class m150101_185401_create_news_table extends Migration
{
    public function safeUp()
    {
        $this->createTable('news', [
            'id' => $this->primaryKey(),
            'title' => $this->string()->notNull(),
            'content' => $this->text(),
        ]);

        $this->insert('news', [
            'title' => 'test 1',
            'content' => 'content 1',
        ]);
    }

    public function safeDown()
    {
        $this->delete('news', ['id' => 1]);
        $this->dropTable('news');
    }
}

Обратите внимание, что обычно, когда вы выполняете несколько операций с базой данных в методе safeUp(), вам следует изменить порядок их выполнения в методе safeDown(). В приведенном выше примере мы сначала создаем таблицу, а затем вставляем строку в safeUp(); в то время как в методе safeDown() мы сначала удаляем строку, а затем удаляем таблицу.

Примечание: Не все СУБД поддерживают транзакции. И некоторые запросы к базе данных не могут быть помещены в транзакцию. Для примеров см. неявную фиксацию. В этом случае вы по-прежнему должны реализовать методы up() и down().

Методы доступа к базе данных

Базовый класс миграции yii\db\Migration предоставляет набор методов для доступа к базам данных и манипулирования ими. Вы можете заметить, что эти методы имеют названия, аналогичные методам DAO, предоставляемым классом yii\db\Command. Например, метод yii\db\Migration::createTable() позволяет создавать новые таблицы, точно так же, как это делает метод yii\db\Command::createTable().

Преимущества использования методов, предоставляемых классом yii\db\Migration, заключаются в том, что вам не нужно явно создавать экземпляры класса yii\db\Command, а выполнение каждого метода автоматически отобразит полезные сообщения, указывающие какие операции с базой данных были выполнены и сколько времени они заняли.

Ниже приведен список всех этих методов доступа к базе данных:

  • execute(): выполнение SQL-запроса
  • insert(): вставка одной строки
  • batchInsert(): вставка нескольких строк
  • update(): обновление строк
  • delete(): удаление строк
  • createTable(): создание таблицы
  • renameTable(): переименование таблицы
  • dropTable(): удаление таблицы
  • truncateTable(): удаление всех строк в таблице
  • addColumn(): добавление столбца
  • renameColumn(): переименование столбца
  • dropColumn(): удаление столбца
  • alterColumn(): изменение столбца
  • addPrimaryKey(): добавление первичного ключа
  • dropPrimaryKey(): удаление первичного ключа
  • addForeignKey(): добавление внешнего ключа
  • dropForeignKey(): удаление внешнего ключа
  • createIndex(): создание индекса
  • dropIndex(): удаление индекса
  • addCommentOnColumn(): добавление комментария к столбцу
  • dropCommentFromColumn(): удаление комментария из столбца
  • addCommentOnTable(): добавление комментария к таблице
  • dropCommentFromTable(): удаление комментария из таблицы

Справочная информация: Класс yii\db\Migration не предоставляет метод для запроса данных из базы данных. Это связано с тем, что обычно не нужно отображать дополнительные сообщения о получении данных из базы данных. Также потому, что вы можете использовать мощный Query Builder для построения и выполнения сложных запросов.

Примечание: При манипулировании данными с помощью миграции вы можете найти полезным использование ваших классов Active Record для этого, так как часть логики уже реализована там. Однако имейте в виду, что в отличие от кода, написанного в миграциях, который предназначен для постоянства, логика приложения может изменяться. Поэтому при использовании Active Record в коде миграции изменения в логике слоя Active Record могут случайно сломать существующие миграции. По этой причине код миграции должен оставаться независимым от другой логики приложения, такой как классы Active Record.

Применение миграций

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

yii migrate

Эта команда покажет все миграции, которые еще не были применены. Если вы подтвердите, что хотите применить эти миграции, она запустит метод up() или safeUp() в каждом новом классе миграции, один за другим, в порядке возрастания значений timestamp. Если какая-либо из миграций завершится ошибкой, команда завершится, не применяя остальные миграции.

Подсказка: В случае, если у вас нет командной строки на вашем сервере, вы можете попробовать расширение webshell.

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

Справочная информация: Инструмент миграций автоматически создаст таблицу migration в базе данных, указанной параметром db команды. По умолчанию база данных определяется компонентом приложения db.

Иногда вы можете захотеть применить только одну или несколько новых миграций вместо всех доступных. Вы можете сделать это, указав количество миграций, которые вы хотите применить, при запуске команды. Например, следующая команда попытается применить следующие три доступные миграции:

yii migrate 3

Вы также можете явно указать конкретную миграцию, к которой должна быть мигрирована база данных, используя команду migrate/to в одном из следующих форматов:

yii migrate/to 150101_185401                      # using timestamp to specify the migration
yii migrate/to "2015-01-01 18:54:01"              # using a string that can be parsed by strtotime()
yii migrate/to m150101_185401_create_news_table   # using full name
yii migrate/to 1392853618                         # using UNIX timestamp

Если есть какие-либо непримененные миграции, предшествующие указанной, они все будут применены перед применением указанной миграции.

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

Отмена миграций

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

yii migrate/down     # revert the most recently applied migration
yii migrate/down 3   # revert the most 3 recently applied migrations

Примечание: Не все миграции обратимы. Попытка отменить такие миграции приведет к ошибке и остановит весь процесс отмены.

Повторное применение миграций

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

yii migrate/redo        # redo the last applied migration
yii migrate/redo 3      # redo the last 3 applied migrations

Примечание: Если миграция необратима, вы не сможете ее повторно применить.

Список миграций

Чтобы узнать, какие миграции были применены, а какие нет, вы можете использовать следующие команды:

yii migrate/history     # showing the last 10 applied migrations
yii migrate/history 5   # showing the last 5 applied migrations
yii migrate/history all # showing all applied migrations

yii migrate/new         # showing the first 10 new migrations
yii migrate/new 5       # showing the first 5 new migrations
yii migrate/new all     # showing all new migrations

Изменение истории миграций

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

yii migrate/mark 150101_185401                      # using timestamp to specify the migration
yii migrate/mark "2015-01-01 18:54:01"              # using a string that can be parsed by strtotime()
yii migrate/mark m150101_185401_create_news_table   # using full name
yii migrate/mark 1392853618                         # using UNIX timestamp

Команда изменит таблицу migration, добавив или удалив определенные строки, чтобы указать, что база данных применяла миграции до указанной. Эта команда не будет применять или отменять миграции.

Настройка миграций

Существует несколько способов настройки команды миграции.

Использование параметров командной строки

Команда миграции поставляется с несколькими параметрами командной строки, которые могут быть использованы для настройки ее поведения:

  • interactive: boolean (по умолчанию true), указывает, выполнять ли миграции в интерактивном режиме. Когда это true, пользователя попросят подтвердить перед выполнением определённых действий. Возможно, следует установить это значение в false, если команда используется в фоновом процессе.

  • migrationPath: string|array (по умолчанию @app/migrations), указывает директорию, в которой хранятся все файлы классов миграций. Это может быть путь к директории или путь псевдоним. Обратите внимание, что директория должна существовать, иначе команда может вызвать ошибку. С версии 2.0.12 можно указать массив для загрузки миграций из нескольких источников.

  • migrationTable: string (по умолчанию migration), указывает имя таблицы базы данных для хранения информации о истории миграций. Таблица будет автоматически создана командой, если её не существует. Вы также можете вручную создать её, используя структуру version varchar(255) primary key, apply_time integer.

  • db: string (по умолчанию db), указывает идентификатор компонента базы данных приложения. Он представляет базу данных, которая будет мигрирована с помощью этой команды.

  • templateFile: string (по умолчанию @yii/views/migration.php), указывает путь к файлу шаблона, который используется для генерации файлов скелета класса миграции. Это может быть путь к файлу или путь псевдоним. Файл шаблона — это PHP-скрипт, в котором вы можете использовать предопределённую переменную с именем $className для получения имени класса миграции.

  • generatorTemplateFiles: array (по умолчанию `[

      'create_table' => '@yii/views/createTableMigration.php',
      'drop_table' => '@yii/views/dropTableMigration.php',
      'add_column' => '@yii/views/addColumnMigration.php',
      'drop_column' => '@yii/views/dropColumnMigration.php',
      'create_junction' => '@yii/views/createTableMigration.php'
    

    ]`), указывает файлы шаблонов для генерации кода миграций. Более подробную информацию см. в разделе "Генерация миграций".

  • fields: массив строк определений столбцов, используемых для создания кода миграций. По умолчанию []. Формат каждого определения — COLUMN_NAME:COLUMN_TYPE:COLUMN_DECORATOR. Например, --fields=name:string(12):notNull создаёт строковый столбец размером 12, который не null.

Следующий пример демонстрирует, как использовать эти параметры.

Например, если мы хотим мигрировать модуль forum, файлы миграций которого расположены в директории migrations модуля, мы можем использовать следующую команду:

# migrate the migrations in a forum module non-interactively
yii migrate --migrationPath=@app/modules/forum/migrations --interactive=0

Глобальная настройка команды

Вместо ввода одних и тех же значений параметров каждый раз при выполнении команды миграции, вы можете настроить их один раз для всех в конфигурации приложения, как показано ниже:

return [
    'controllerMap' => [
        'migrate' => [
            'class' => 'yii\console\controllers\MigrateController',
            'migrationTable' => 'backend_migration',
        ],
    ],
];

С указанной выше конфигурацией каждый раз при выполнении команды миграции будет использоваться таблица backend_migration для записи истории миграций. Вам больше не нужно указывать её через параметр командной строки migrationTable.

Пространства имён миграций

С версии 2.0.10 вы можете использовать пространства имён для классов миграций. Вы можете указать список пространств имён миграций через migrationNamespaces. Использование пространств имён для классов миграций позволяет вам использовать несколько источников для миграций. Например:

return [
    'controllerMap' => [
        'migrate' => [
            'class' => 'yii\console\controllers\MigrateController',
            'migrationNamespaces' => [
                'app\migrations', // Common migrations for the whole application
                'module\migrations', // Migrations for the specific project's module
                'some\extension\migrations', // Migrations for the specific extension
            ],
        ],
    ],
];

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

При работе с миграциями в пространствах имён: создании новых, откате и т. д., вы должны указывать полное пространство имён перед именем миграции. Обратите внимание, что символ обратного слэша (\) обычно считается специальным символом в оболочке, поэтому вам необходимо правильно экранировать его, чтобы избежать ошибок оболочки или неправильного поведения. Например:

yii migrate/create 'app\\migrations\\createUserTable'

Примечание: миграции, указанные через migrationPath, не могут содержать пространство имён, миграции в пространствах имён могут быть применены только через свойство yii\console\controllers\MigrateController::$migrationNamespaces.

С версии 2.0.12 свойство migrationPath также принимает массив для указания нескольких директорий, содержащих миграции без пространства имён. Это в основном добавлено для использования в существующих проектах, которые используют миграции из разных расположений. Эти миграции в основном поступают из внешних источников, таких как расширения Yii, разработанные другими разработчиками, которые не могут быть легко изменены для использования пространств имён при начале использования нового подхода.

Разделенные миграции

Иногда использование единой истории миграций для всех миграций проекта нежелательно. Например, вы можете установить расширение «блог», которое содержит полностью отделённую функциональность и содержит собственные миграции, которые не должны влиять на миграции, предназначенные для основной функциональности проекта.

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

return [
    'controllerMap' => [
        // Common migrations for the whole application
        'migrate-app' => [
            'class' => 'yii\console\controllers\MigrateController',
            'migrationNamespaces' => ['app\migrations'],
            'migrationTable' => 'migration_app',
            'migrationPath' => null,
        ],
        // Migrations for the specific project's module
        'migrate-module' => [
            'class' => 'yii\console\controllers\MigrateController',
            'migrationNamespaces' => ['module\migrations'],
            'migrationTable' => 'migration_module',
            'migrationPath' => null,
        ],
        // Migrations for the specific extension
        'migrate-rbac' => [
            'class' => 'yii\console\controllers\MigrateController',
            'migrationPath' => '@yii/rbac/migrations',
            'migrationTable' => 'migration_rbac',
        ],
    ],
];

Обратите внимание, что для синхронизации базы данных вам теперь необходимо выполнить несколько команд вместо одной:

yii migrate-app
yii migrate-module
yii migrate-rbac

Миграция нескольких баз данных

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

yii migrate --db=db2

Вышеупомянутая команда применит миграции к базе данных db2.

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

<?php

use yii\db\Migration;

class m150101_185401_create_news_table extends Migration
{
    public function init()
    {
        $this->db = 'db2';
        parent::init();
    }
}

Вышеуказанная миграция будет применена к db2, даже если вы укажете другую базу данных через параметр командной строки db. Обратите внимание, что история миграций по-прежнему будет записываться в базе данных, указанной параметром командной строки db.

Если у вас есть несколько миграций, использующих одну и ту же базу данных, рекомендуется создать базовый класс миграции с вышеуказанным кодом init(). Затем каждый класс миграции может расширять этот базовый класс.

Подсказка: помимо установки свойства db, вы также можете работать с разными базами данных, создавая новые подключения к ним в классах миграций. Затем вы можете использовать методы DAO с этими подключениями для работы с разными базами данных.

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

yii migrate --migrationPath=@app/migrations/db1 --db=db1
yii migrate --migrationPath=@app/migrations/db2 --db=db2
...

Первая команда применит миграции в @app/migrations/db1 к базе данных db1, вторая команда применит миграции в @app/migrations/db2 к db2 и так далее.

© 2008–2017 by Yii Software LLC
Licensed under the three clause BSD license.
http://www.yiiframework.com/doc-2.0/guide-db-migrations.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API