carono/yii2-migrate

为Yii2迁移创建数据库的Trait

1.1.6 2024-05-27 11:41 UTC

This package is auto-updated.

Last update: 2024-08-28 04:28:25 UTC


README

Scrutinizer Code Quality Latest Stable Version Total Downloads License Build Status Code Coverage

[英文] [俄语]

MigrationTrait

为了扩展迁移功能,您必须添加一个Trait \carono\yii2migrate\traits\MigrationTrait 或从 \carono\yii2migrate\Migration 扩展迁移类

public function tableOptions()

返回创建表的设置数组,其中键是数据库驱动程序的名称。
通过createTable()创建表时,如果没有指定属性,将从中获取此函数

    public function tableOptions()
    {
        return [
            'mysql' => 'CHARACTER SET utf8 COLLATE utf8_general_ci ENGINE=InnoDB'
        ];
    }

public function newTables()

返回一个数组,其中键是表名,值是带有类型的列。
如果您调用函数 $this->upNewTables(),将通过createTable()创建所有指定的表
如果您调用函数 $this->downNewTables(),将通过dropTable()删除所有指定的表

    public function newTables()
    {
        return [
            '{{%logs}}' => [
                'data' => $this->string(),
                '@tableOptions' => [
                    'mysql' => 'CHARACTER SET utf8 COLLATE utf8_general_ci ENGINE=MyISAM'
                ]
            ]
        ];
    }
    
    public function safeUp()
    {
        $this->upNewTables();
    }
    
    public function safeUp()
    {
        $this->downNewTables();
    }

pubic function newColumns()

返回一个数组,其中键是现有表的名称,值是带有类型的列。
如果您调用函数 $this->upNewColumns(),将通过addColumn()创建所有指定的列
如果您调用函数 $this->downNewColumns(),将在dropColumn()之后删除所有指定的列

    public function newColumns()
    {
        return [
            '{{%company}}' => [
                'address' => $this->string(),
                'is_active' => $this->boolean()
            ]
        ];
    }
    
    public function safeUp()
    {
        $this->upNewColumns();
    }
    
    public function safeUp()
    {
        $this->downNewColumns();
    }    

public function newIndex()

返回一个数组,其中键是现有表的名称,值是通过 $this->index() 获取的索引参数。
如果您调用函数 $this->upNewIndex(),将通过createIndex()创建所有指定的索引
如果您调用函数 $this->downNewIndex(),将使用dropIndex()删除所有指定的列

    public function newIndex()
    {
        return [
            '{{%company}}' => [
                $this->index()->columns(['name'])->unique(true)
            ],
        ];
    }
    
    
    public function safeUp()
    {
        $this->upNewIndex();
    }
    
    public function safeUp()
    {
        $this->downNewIndex();
    }        

处理外键

通过表名仅指定外键来创建表

$this->createTable('{{%user}}', [
    'id' => $this->primaryKey(),
    'company_id' => $this->foreignKey('{{%company}}')
]);

添加外键列

$this->addColumn('{{%user}}', 'company_id', $this->foreignKey('{{%company}}'));

向现有列添加外键

$this->alterColumn('{{%user}}', 'company_id', $this->foreignKey('{{%company}}'));

添加具有自动命名的外键

$this->addForeignKey(null, '{{%user}}', 'photo_id', '{{%photo}}', 'id');

按列名删除外键

$this->dropForeignKeyByColumn('{{%user}}', 'company_id');

处理索引

创建具有自动名称的索引

$this->createIndex(null, '{{%user}}', 'name');

按列名删除索引

$this->dropIndexByColumn('{{%user}}', 'name');

(!) 注意,如果索引中有多个列,则需要按必要顺序指定它们。如果有多个具有此类设置和顺序的索引,则将删除所有这些索引。 (!) 与postgreSQL不正确地工作 (yiisoft/yii2#16639)

$this->createIndex(null, '{{%user}}', ['name', 'surname']);
$this->dropIndexByColumn('{{%user}}', ['name', 'surname']);

枢纽表

要实现多对多表,可以使用 $this->pivot() 函数,将创建一个具有2个键的表。枢纽表中的键名是自动生成的,因此可以通过refColumn()和sourceColumn()设置

通过创建表创建枢纽表。结果是表 {{%user}}[id] {{%pv_user_photos}}[user_id, photo_id]

$this->createTable('{{%user}}', ['id' => $this->primaryKey(), 'photos' => $this->pivot('{{%photo}}')]);

通过添加列创建枢纽表。

$this->addColumn('{{%user}}', 'photos', $this->pivot('{{%photo}}'));

指定枢纽表名称

$this->addColumn('{{%user}}', 'photos', $this->pivot('{{%photo}}')->tableName('{{%album}}'));

PivotTrait

帮助处理枢纽表的Trait

$company - 公司表模型(需要PivotTrait)
$user - 用户表模型
PvCompanyDirector - 由两个模型(公司和学生)组成的枢纽表
数据透视表 - 包含2个主键的表

向PvCompanyDirector表中添加了一组终端用户公司

$company->addPivot($user, PvCompanyDirector::class, $attributes = []);

获取公司-用户捆绑的PvCompanyDirector模型

$company->getPivot($model, PvCompanyDirector::class, $condition = []);

删除了一组用户-公司

$company->deletePivot($model, PvCompanyDirector::class);

删除此公司PvCompanyDirector中的所有用户

$company->deletePivots(PvCompanyDirector::class);

保存到临时链接变量中,以便以后使用

$company->storagePivot($user, PvCompanyDirector::class, ['hire_at' => '2010-01-01 00:00:00']);
$users = $company->getStoragePivots(PvCompanyDirector::class)); // The list of models that have been added earlier

临时变量的关联保护。
$clear - 在添加之前完全清除所有链接

$company->savePivots($clear); // Save all links added via storagePivot

迁移类行为的变化

public function createIndex($name, $table, $columns, $unique = false)

  • $name可以指定null以自动生成索引名称

public function createTable($table, $columns, $options = null)

  • $columns支持$ this->foreignKey()和$ this->pivot()
  • 如果未指定$options,则从$ this->tableOptions中提取选项,如果没有选项,则从到$ columns

public function alterColumn($table, $column, $type)

  • $type支持类型$ this->foreignKey()

public function addColumn($table, $column, $type)

  • $type支持类型$ this->foreignKey()和$ this->pivot()

public function addPrimaryKey($name, $table, $columns)

  • $name可以指定null以自动生成索引名称

public function dropColumn($table, $column)

  • 在删除表之前,外键被清除

完整迁移的示例

<?php

use yii\db\Migration;
use \yii\db\Schema;
/**
 * Class m180712_120503_init
 */
class m180712_120503_init extends Migration
{
    use \carono\yii2migrate\traits\MigrationTrait;

    public function tableOptions()
    {
        return [
            'mysql' => 'CHARACTER SET utf8 COLLATE utf8_general_ci ENGINE=InnoDB'
        ];
    }

    public function newTables()
    {
        return [
            '{{%logs}}' => [
                'data' => $this->string(),
                '@tableOptions' => [
                    'mysql' => 'CHARACTER SET utf8 COLLATE utf8_general_ci ENGINE=MyISAM'
                ]
            ],
            '{{%user}}' => [
                'id' => $this->primaryKey(),
                'name' => $this->string(),
                'parents' => $this->pivot('{{%user}}') // Create a pivot table on itself
            ],
            '{{%photo}}' => [
                'id' => $this->primaryKey(),
                'user_id' => $this->integer()
            ],
            '{{%company}}' => [
                'id' => $this->primaryKey(),
                'name' => $this->string(),
                // Create a pivot table {{%pv_company_directors}}
                'directors' => $this->pivot('{{%user}}', 'director_id')->columns(
                    [
                        'hire_at' => $this->dateTime(),
                        // A foreign key with SET NULL rule is when you remove data from {{%user}}
                        'hired_id' => $this->foreignKey('{{%user}}', null)->onDeleteNull()->unsigned()
                    ]
                ),
                '@tableOptions' => [
                    'mysql' => 'CHARACTER SET utf8 COLLATE utf8_general_ci ENGINE=InnoDB'
                ]
            ],
            '{{%pv_company_user_photo}}' => [
                // Create a PivotTable of several keys
                'company_id' => $this->foreignKey('{{%company}}', null, Schema::TYPE_PK),
                'user_id' => $this->foreignKey('{{%user}}', null, Schema::TYPE_PK),
                'photo_id' => $this->foreignKey('{{%photo}}', null, Schema::TYPE_PK),
            ]
        ];
    }

    public function newColumns()
    {
        return [
            '{{%company}}' => [
                // Create a FK to user
                'user_id' => $this->foreignKey('{{%user}}'),
                // Create a pivot table employees
                'users' => $this->pivot('{{%user}}')->tableName('{{%employees}}')
            ]
        ];
    }

    public function newIndex()
    {
        return [
            '{{%company}}' => [
                $this->index()->columns(['name'])->unique(true)->length(10)
            ],
        ];
    }

    public function safeUp()
    {
        $this->upNewTables();
        $this->upNewColumns();
        // Add a FK to an existing column
        $this->alterColumn('{{%photo}}', 'user_id', $this->foreignKey('{{%user}}'));
        $this->upNewIndex();
        $this->createIndex(null, '{{%user}}', 'name');
    }

    public function safeDown()
    {
        $this->dropIndexByColumn('{{%user}}', 'name');
        $this->downNewIndex();
        // Remove the FK on the column name
        $this->dropForeignKeyByColumn('{{%photo}}', 'user_id');
        $this->downNewColumns();
        $this->downNewTables();
    }
}

生成的数据库模式