Yii 2 で既存のデータベースからマイグレーションコードを生成するコマンドを作る

Yii 2 で既存のデータベースからマイグレーションコードを生成するエクステンションを作りました。わりと力技な感じになっていますが、テーブルとか用意されているのであれば、楽ができるかもしれないので、是非使ってみてください。

## デモ

![gif](https://raw.githubusercontent.com/jamband/jamband.github.io/master/images/yii2-schemadump.gif)

## インストール

Composer でインストールします。本番環境では必要ないので require-dev でインストールするようにします。

```
php composer.phar require --dev --prefer-dist jamband/yii2-schemadump "*"
```

composer.json に直接書くなら以下のようにして `composer update` して下さい。

```composer.json
{
    "require-dev": {
        "jamband/yii2-schemadump": "*"
    },
}

```

## 使うための準備

config/db.php でデータベースの設定をします。

```php:db.php
return [
    'class' => yii\db\Connection::class,
    'dsn' => 'mysql:host=localhost;dbname=db_name',
    'username' => 'your_username',
    'password' => 'your_password',
    'charset' => 'utf8',
];
```

あと、以下のコードを config/console.php に追加します。

```php:console.php
return [
    ...
    'components' => [
        ...
    ],
    'controllerMap' => [
        'migrate' => [
            'class' => yii\console\controllers\MigrateController::class,
            'templateFile' => '@jamband/schemadump/template.php',
        ],
        'schemadump' => [
            'class' => jamband\schemadump\SchemaDumpController::class,
            'db' => [
                'class' => yii\db\Connection::class,
                'dsn' => 'mysql:host=localhost;dbname=existing_database_name',
                'username' => 'your_username',
                'password' => 'your_password',
            ],
        ],
    ],
    ...
];
```

`schemadump` コマンドはどのクラスのものを使用するかを controllerMap 内で指定しています。あと `migrate/create` コマンドでマイグレーションファイルを作成するときのテンプレートファイルを yii2-schemadump のものに置き換えています。これで準備は OK 。

## 使ってみる

プロジェクトルートまで移動して yii2-schemadump が利用可能かどうかチェックします。

```
./yii help
```

コマンド一覧に `schemadump` があれば使える状態です。何か手元にある既存のデータベースがあれば以下のようにコマンドを実行してみてください。

```
./yii schemadump
```

標準出力にマイグレーションコードが出力されるかと思います。あとはこれをコピペしてマイグレーションファイルに貼り付ければ OK です。テーブルの削除用に `schemadump/drop` というコマンドもあります。

```
./yii schemadump/drop
```

これでデータベースが用意されている場合は、ちまちまマイグレーションファイルを手書きで記述する必要がなくなるので便利かなと思います。

## 出力対象

すべてのデータベースをサポートするのは難しいですが、以下のものはサポートするようにしました。今後変更があるかもしれないですが、現在サポートしているものだけ挙げておきます。

- 型
- サイズ
- Unsigned
- NOT NULL
- デフォルト値
- コメント
- ユニークキー
- 外部キー制約
- 複数の主キー
- 自動インクリメントでない主キー
- MySQL の ENUM 型

外部キー制約名は自動で作られます。また ON DELETE, ON UPDATE はどちらとも null に設定されているので、追加が必要になる場合があります。

`schemadump/drop` コマンドで生成される `$this->dropTable()` は外部キー制約に対して順不同なので、コメントを参考にしつつ上手く順番を変更する必要があります。

セカンダリインデックスなどは手動で記述する必要があります。


## エクステンションを作るには？

Yii 2 でエクステンションを作るのに日本語ガイドの [エクステンションを作成する](https://github.com/yiijan/yii2-i18n-ja/blob/master/docs/guide-ja/structure-extensions.md#%E3%82%A8%E3%82%AF%E3%82%B9%E3%83%86%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%B3%E3%82%92%E4%BD%9C%E6%88%90%E3%81%99%E3%82%8B-) がとても参考になりました。Yii 1.x のときよりもかなり事細かく書かれています。

## 関連リンク

- [jamband/yii2-schemadump](https://github.com/jamband/yii2-schemadump)
- [The Definitive Guide to Yii 2.0: Database Migration](http://www.yiiframework.com/doc-2.0/guide-db-migrations.html)
- [The Definitive Guide to Yii 2.0: Console applications](http://www.yiiframework.com/doc-2.0/guide-tutorial-console.html)

- [yii2-migration-utility](http://www.yiiframework.com/extension/yii2-migration-utility/)