Миграции в модулях и расширениях в Yii2.
  • 989

Как работать с миграциями в модулях и расширениях yii2.

Автор: admin | 22 марта (Пт.) 2019г. в 21ч.51м.

Создание миграции в модуле или расширении yii2.

Для создания миграции в приложении используется команда в консоли yii migrate/create <name> .Например, после выполнения данной команды 
 yii migrate/create create_user_table сгенерируется класс миграции в директории, которая определена для миграций в ядре или конфигурации фреймворка. Для того, чтобы создать миграцию в модуле или расширении yii2, нужно добавить параметр migrationPath, который содержит путь к папке миграций в нужном месте. Вот как эта команда может выглядеть для модуля или расширения:
//migrationPath содержит путь к папке миграций
yii migrate/create comments_table --migrationPath=@coderius/comments/migrations

//Или сокращенная форма параметра migrationPath p
yii migrate/create comments_table p=@coderius/comments/migrations?
Обратите внимание, что для указания пути можно использовать алиасы, которые должны быть естесственно установлены в приложении. Например, после установки расширения, можно указать алиас установленный для расширения или зарегестрировать алиас для модуля в конфигурации приложения. Можно воспользоваться уже имеющимися псевдонимами путей, которые уже определены во фреймворке:
<?php

//Файл bootstrap.php в advanced фаблоне yii2

Yii::setAlias('@common', dirname(__DIR__));
Yii::setAlias('@frontend', dirname(dirname(__DIR__)) . '/frontend');
Yii::setAlias('@backend', dirname(dirname(__DIR__)) . '/backend');
Yii::setAlias('@console', dirname(dirname(__DIR__)) . '/console');

//Тут создаем алиас к папке модулей, которую сами создадим для расположения нами создаваемых модулей
Yii::setAlias('@modules', dirname(dirname(__DIR__)) . '/modules');?

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

Применение всех миграций в модуле (или расширении). Команда в терминале для применения конкретной миграции:
//Имя файла миграции m190321_064014_insert_content_in_comments_table
yii migrate/to m190321_064014_insert_content_in_comments_table --migrationPath=@coderius/comments/migrations?

//То же самое,но с псевдонимом параметра migrationPath
yii migrate/to m190321_064014_insert_content_in_comments_table p=@coderius/comments/migrations

Применение всех миграций в модуле:

//Применение всех миграций в модуле
yii migrate --migrationPath=@coderius/comments/migrations??

//Применить 5 последних миграций
yii migrate 5 --migrationPath=@coderius/comments/migrations??

Перезагрузка, отмена миграций.

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

//Перезагрузка миграции
yii migrate/redo m190321_064014_insert_content_in_comments_table --migrationPath=@coderius/comments/migrations?

//Вызов метода down() или safeDown() в указанной миграции
yii migrate/down m190321_064014_insert_content_in_comments_table p=@coderius/comments/migrations?

Сокращенные параметры в миграциях определены в yii\console\controllers\MigrateController в методе:

/**
     * {@inheritdoc}
     * @since 2.0.8
     */
    public function optionAliases()
    {
        return array_merge(parent::optionAliases(), [
            'C' => 'comment',
            'f' => 'fields',
            'p' => 'migrationPath',
            't' => 'migrationTable',
            'F' => 'templateFile',
            'P' => 'useTablePrefix',
            'c' => 'compact',
        ]);
    }
Вот откуда берется сокращение для migrationPath

Установка конфигурации для миграций.

Кроме того, чтобы указывать путь к конкретной папке миграции в командной строке, можно также настроить данное свойство в конфигурации. Так, в advanced приложении yii2 можно указать данную настройку в controllerMap (console/config/main.php):
'controllerMap' => [
        //Create migration in module extention -
        //yii migrate/ --migrationPath=coderius/comments/migrations create_comments_table
        'migrate-mymodule' => [
            'class' => 'yii\console\controllers\MigrateController',
            'migrationNamespaces' => [
                'coderius\comments\migrations',
            ],
            'migrationPath' => '@coderius/comments/migrations', // allows to disable not namespaced migration completely
        ],
    ],?

Теперь с такой конфигурацией можно не писать путь к папке миграций в консоли:

yii migrate-mymodule/history

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

'controllerMap' => [
        //Create migration in module extention -
        //yii migrate/ --migrationPath=coderius/comments/migrations create_comments_table
        'migrate-mymodule' => [
            'class' => 'yii\console\controllers\MigrateController',
            'migrationNamespaces' => [
                'coderius\comments\migrations',
            ],
            'migrationTable' => 'migration_mymodule',
            'migrationPath' => '@coderius/comments/migrations', // allows to disable not namespaced migration completely
        ],
    ],??

Перед тем, как использовать отдельную таблицу миграций для модуля, нужно ее создать с помощью тех же миграций или вручную.
Посмотрим, как создается таблица для миграций в приложении, которая генерирует таблицу migration при первом запуске yii migrate  из консоли (код в yii\console\controllers\MigrateController):

/**
* Creates the migration history table.
*/
    protected function createMigrationHistoryTable()
    {
        $tableName = $this->db->schema->getRawTableName($this->migrationTable);
        $this->stdout("Creating migration history table \"$tableName\"...", Console::FG_YELLOW);
        $this->db->createCommand()->createTable($this->migrationTable, [
            'version' => 'varchar(' . static::MAX_NAME_LENGTH . ') NOT NULL PRIMARY KEY',
            'apply_time' => 'integer',
        ])->execute();
        $this->db->createCommand()->insert($this->migrationTable, [
            'version' => self::BASE_MIGRATION,
            'apply_time' => time(),
        ])->execute();
        $this->stdout("Done.\n", Console::FG_GREEN);
    }

Создадим теперь класс миграции для своего модуля. Данная миграция будет генерировать отдельную таблицу в базе данных для хранения миграций нашего модуля. Выполняем в консоли команду:

yii migrate/create --migrationPath=@coderius/comments/migrations create_table_migration_comment

У нас сгенерировался по указанному пути класс миграции:

<?php

use yii\db\Migration;

/**
 * Class m190321_143326_create_table_migration_comment
 */
class m190321_143326_create_table_migration_comment extends Migration
{
    /**
     * {@inheritdoc}
     */
    public function safeUp()
    {

    }

    /**
     * {@inheritdoc}
     */
    public function safeDown()
    {
        echo "m190321_143326_create_table_migration_comment cannot be reverted.\n";

        return false;
    }

    /*
    // Use up()/down() to run migration code without a transaction.
    public function up()
    {

    }

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

        return false;
    }
    */
}

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

<?php

use yii\db\Migration;

/**
 * Class m190321_143326_create_table_migration_comment.
 */
class m190321_143326_create_table_migration_comment extends Migration
{
    /**
     * @var string the name of the table for keeping applied migration information
     */
    protected $migrationTable = '{{%migration_comment}}';

    /**
     * {@inheritdoc}
     * yii migrate/to m190321_143326_create_table_migration_comment  --migrationPath=@coderius/comments/migrations.
     */
    public function safeUp()
    {
        $tableOptions = null;
        if ('mysql' === $this->db->driverName) {
            $tableOptions = 'CHARACTER SET utf8 COLLATE utf8_general_ci ENGINE=InnoDB';
        }

        $this->createTable($this->migrationTable, [
            'version' => 'varchar(180) NOT NULL PRIMARY KEY',
            'apply_time' => $this->integer(11)->defaultValue(null),
        ], $tableOptions);

        // $this->addPrimaryKey('PRIMARY', $this->migrationTable, 'version');
    }

    /**
     * {@inheritdoc}
     * yii migrate/down 1 m190321_143326_create_table_migration_comment  --migrationPath=@coderius/comments/migrations.
     */
    public function safeDown()
    {
        $this->dropTable($this->migrationTable);
    }

    /*
    // Use up()/down() to run migration code without a transaction.
    public function up()
    {

    }

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

        return false;
    }
    */
}

Применим миграцию:

yii migrate/to m190321_143326_create_table_migration_comment  --migrationPath=@coderius/comments/migrations

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

'migrationTable' => 'migration_comment',

Теперь yii migrate-mymodule/history  будет работать только для нашей таблицы.

Если Вам будет интересно, посмотрите видео про миграции в Yii2. Видео на английском, но все предельно понятно. Так, для общего развития стоит глянуть :)


Приветствую!

Меня зовут Сергей. Я - автор этого блога.

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