カテゴリー
Linux

Laravel 5.5 既存のデータベースからマイグレーションファイルを一発で生成した手順

まとめ

バーション情報

  • Laravel Framework 5.5.45
  • Laravel Migrations Generator v2.0.2

マイグレーションファイル生成の対象としたデータベース情報

  • インストールし、テーマやプラグインは追加・削除せずにアップデートを行なった WordPress 5.2.1 のデータベース

Laravel Migrations Generator をインストール

composer require --dev "xethron/migrations-generator"

実際の様子です。 Composer は Docker コンテナを使い捨てで使用しているので、上述のコマンドとは完全には一致していません。また、 Carbon のバージョンが古いと警告が出ていますが、これは Laravel 5.5 をインストールするときにも出ていました。ですので、今回の Laravel Migrations Generator のインストールが原因ではないと思います。

$ docker-compose run --rm composer require --dev "xethron/migrations-generator"
Using version ^2.0 for xethron/migrations-generator
./composer.json has been updated
Loading composer repositories with package information
Updating dependencies (including require-dev)
Package operations: 5 installs, 0 updates, 0 removals
  - Installing doctrine/event-manager (v1.0.0): Downloading (100%)
  - Installing doctrine/cache (v1.8.0): Downloading (100%)
  - Installing doctrine/dbal (v2.9.2): Downloading (100%)
  - Installing xethron/laravel-4-generators (3.1.1): Downloading (100%)
  - Installing xethron/migrations-generator (v2.0.2): Downloading (100%)
doctrine/cache suggests installing alcaeus/mongo-php-adapter (Required to use legacy MongoDB driver)
Package phpunit/phpunit-mock-objects is abandoned, you should avoid using it. No replacement was suggested.
Writing lock file
Generating optimized autoload files
*******************************************
 /!\ Warning, you're using a deprecated
 ¨¨¨ version of Carbon, we will soon stop
     providing support and update for 1.x
     versions, please upgrade to Carbon 2.
*******************************************

Most features of Carbon 1 are still available in Carbon 2.
See how to migrate: https://carbon.nesbot.com/docs/#api-carbon-2

Please consider upgrading your Laravel dependencies to be compatible with Carbon 2:
  - laravel/framework at least to version 5.8.0

If you can't update Laravel, check https://carbon.nesbot.com/ to see how to
install Carbon 2 using alias version and our adapter kylekatarnls/laravel-carbon-2

You can run './vendor/bin/upgrade-carbon' to get help in updating carbon and other frameworks and libraries that depend on it.
> Illuminate\Foundation\ComposerScripts::postAutoloadDump
> @php artisan package:discover
Discovered Package: fideloper/proxy
Discovered Package: laravel/tinker
Discovered Package: nesbot/carbon
Discovered Package: xethron/migrations-generator
Package manifest generated successfully.
$

Laravel Migrations Generator の help

# php artisan help migrate:generate
Usage:
  migrate:generate [options] [--] [<tables>]

Arguments:
  tables                              A list of Tables you wish to Generate Migrations for separated by a comma: users,posts,comments

Options:
  -c, --connection[=CONNECTION]       The database connection to use. [default: "mysql"]
  -t, --tables[=TABLES]               A list of Tables you wish to Generate Migrations for separated by a comma: users,posts,comments
  -i, --ignore[=IGNORE]               A list of Tables you wish to ignore, separated by a comma: users,posts,comments
  -p, --path[=PATH]                   Where should the file be created?
      --defaultIndexNames             Don't use db index names for migrations
      --defaultFKNames                Don't use db foreign key names for migrations
  -h, --help                          Display this help message
  -q, --quiet                         Do not output any message
  -V, --version                       Display this application version
      --ansi                          Force ANSI output
      --no-ansi                       Disable ANSI output
  -n, --no-interaction                Do not ask any interactive question
      --env[=ENV]                     The environment the command should run under
  -tp, --templatePath[=TEMPLATEPATH]  The location of the template for this generator
  -v|vv|vvv, --verbose                Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug

Help:
  Generate a migration from an existing table structure.
#

マイグレーションファイルの生成実践

  • 実践する前に php artisan migrate は 1 度も行なっていない。
  • "Do you want to log these migrations in the migrations table? [Y/n] :" を y とすると、 生成するマイグレーションファイルをマイグレート実行したことにした情報を migrations テーブルに記録できる。
# php artisan migrate:generate
Using connection: mysql

Generating migrations for: wp_commentmeta, wp_comments, wp_links, wp_options, wp_postmeta, wp_posts, wp_term_relationships, wp_term_taxonomy, wp_termmeta, wp_terms, wp_usermeta, wp_users

 Do you want to log these migrations in the migrations table? [Y/n] :
 > y

Migration table created successfully.

 Next Batch Number is: 1. We recommend using Batch Number 0 so that it becomes the "first" migration [Default: 0] :
 > 0

Setting up Tables and Index Migrations
Created: /var/www/database/migrations/2019_06_02_040048_create_wp_commentmeta_table.php
Created: /var/www/database/migrations/2019_06_02_040048_create_wp_comments_table.php
Created: /var/www/database/migrations/2019_06_02_040048_create_wp_links_table.php
Created: /var/www/database/migrations/2019_06_02_040048_create_wp_options_table.php
Created: /var/www/database/migrations/2019_06_02_040048_create_wp_postmeta_table.php
Created: /var/www/database/migrations/2019_06_02_040048_create_wp_posts_table.php
Created: /var/www/database/migrations/2019_06_02_040048_create_wp_term_relationships_table.php
Created: /var/www/database/migrations/2019_06_02_040048_create_wp_term_taxonomy_table.php
Created: /var/www/database/migrations/2019_06_02_040048_create_wp_termmeta_table.php
Created: /var/www/database/migrations/2019_06_02_040048_create_wp_terms_table.php
Created: /var/www/database/migrations/2019_06_02_040048_create_wp_usermeta_table.php
Created: /var/www/database/migrations/2019_06_02_040048_create_wp_users_table.php

Setting up Foreign Key Migrations


Finished!

#

マイグレーションファイルの生成結果

ファイル

実践時の出力の通りのファイルが生成されました。その中の 1 ファイルの内容です。テーブル名は wp_commentmeta です。

database/migrations/2019_06_02_043145_create_wp_commentmeta_table.php

  • 外部キーは、もともとないのでマイグレーションファイルにもない。
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;

class CreateWpCommentmetaTable extends Migration {

        /**
         * Run the migrations.
         *
         * @return void
         */
        public function up()
        {
                Schema::create('wp_commentmeta', function(Blueprint $table)
                {
                        $table->bigInteger('meta_id', true)->unsigned();
                        $table->bigInteger('comment_id')->unsigned()->default(0)->index('comment_id');
                        $table->string('meta_key')->nullable()->index('meta_key');
                        $table->text('meta_value')->nullable();
                });
        }


        /**
         * Reverse the migrations.
         *
         * @return void
         */
        public function down()
        {
                Schema::drop('wp_commentmeta');
        }

}

このテーブルの CREATE 文は次です。うまくマイグレーションファイルが生成されていることがわかります。

CREATE TABLE `wp_commentmeta` (
  `meta_id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `comment_id` bigint(20) unsigned NOT NULL DEFAULT '0',
  `meta_key` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_520_ci DEFAULT NULL,
  `meta_value` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_520_ci,
  PRIMARY KEY (`meta_id`),
  KEY `comment_id` (`comment_id`),
  KEY `meta_key` (`meta_key`(191))
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_520_ci

データベース

migrations テーブルに、今回生成したファイルを使ってマイグレーション実行したことにするログを残したので、テーブルの中身は次のようになっていました。なお、このコマンド実行以前にマイグレーションを実行したことはなかったため、 migrations テーブルは存在していませんでした。なので、マイグレーションファイル生成によって、 migrations テーブルの作成と、マイグレーションの実行が行われた (実際には行われていないが DB テーブル上は行われたことになった) ことになります。

mysql> select * from migrations;
+----+------------------------------------------------------+-------+
| id | migration                                            | batch |
+----+------------------------------------------------------+-------+
|  1 | 2019_06_02_043145_create_wp_commentmeta_table        |     0 |
|  2 | 2019_06_02_043145_create_wp_comments_table           |     0 |
|  3 | 2019_06_02_043145_create_wp_links_table              |     0 |
|  4 | 2019_06_02_043145_create_wp_options_table            |     0 |
|  5 | 2019_06_02_043145_create_wp_postmeta_table           |     0 |
|  6 | 2019_06_02_043145_create_wp_posts_table              |     0 |
|  7 | 2019_06_02_043145_create_wp_term_relationships_table |     0 |
|  8 | 2019_06_02_043145_create_wp_term_taxonomy_table      |     0 |
|  9 | 2019_06_02_043145_create_wp_termmeta_table           |     0 |
| 10 | 2019_06_02_043145_create_wp_terms_table              |     0 |
| 11 | 2019_06_02_043145_create_wp_usermeta_table           |     0 |
| 12 | 2019_06_02_043145_create_wp_users_table              |     0 |
+----+------------------------------------------------------+-------+
12 rows in set (0.00 sec)

mysql>

ちなみに、 "Next Batch Number is: 1. We recommend using Batch Number 0 so that it becomes the "first" migration [Default: 0] :" で 0 ではなく n (n は "Next Batch Number is: 1." の数字。今回は 1) を指定すると、 php artisan migrate:rollback したときに実際にロールバックされてテーブルは削除されてしまいます。

php artisan migrate で元に戻りますけれども、レコードは当然ながら戻りません。

余談。 WordPress の datetime 型のデフォルト値 ‘0000-00-00 00:00:00’ は問題を引き起こす

それに、今回 WordPress 5.2.1 の DB 情報を使いました。これには問題があって、 p artisan migrate` で元に戻るどころか、エラーとなって落ちました><。

# php artisan migrate

In Connection.php line 664:

  SQLSTATE[42000]: Syntax error or access violation: 1067 Invalid default value for 'comment_date' (SQL: create table `wp_comments` (`comment_ID` bigint unsigned not null auto_increment primary key,
  `comment_post_ID` bigint unsigned not null default '0', `comment_author` text not null, `comment_author_email` varchar(100) not null default '', `comment_author_url` varchar(200) not null default '
  ', `comment_author_IP` varchar(100) not null default '', `comment_date` datetime not null default '0000-00-00 00:00:00', `comment_date_gmt` datetime not null default '0000-00-00 00:00:00', `comment
  _content` text not null, `comment_karma` int not null default '0', `comment_approved` varchar(20) not null default '1', `comment_agent` varchar(255) not null default '', `comment_type` varchar(20)
  not null default '', `comment_parent` bigint unsigned not null default '0', `user_id` bigint unsigned not null default '0') default character set utf8mb4 collate utf8mb4_unicode_ci)


In PDOStatement.php line 119:

  SQLSTATE[42000]: Syntax error or access violation: 1067 Invalid default value for 'comment_date'


In PDOStatement.php line 117:

  SQLSTATE[42000]: Syntax error or access violation: 1067 Invalid default value for 'comment_date'


#

問題の内容は、調べますと、 MySQLの0000-00-00 00:00:00は使ってはならない – そーだいなるらくがき帳 のページが詳しかったです。

もう少し、調べますと、 WordPress はもともとデフォルト値に 0000-00-00 00:00:00 を使っており、 WordPress 的には正しく、 DB ダンプファイルやマイグレーションファイルが悪いわけではありませんでした。

となると、 WordPress のデータベースのみを使い、 Laravel でアプリを開発する場合は、この問題を解決する必要がありそうです。

おわりに

実際に、システムのリプレースという仕事を想定した場合、データベース構造とレコードはそのまま使い、プログラムをゼロから作り直す、という業務は結構あると思います。

Laravel で作ろう、となった場合、テーブルはすでにあるわけですから、それらに対応するマイグレーションファイルを作る、ということは別にやらなくても良いのではないかと、ここまでやってきて何ですが感じました。

データベース構造はそのまま使い、データはいらない、というケースであれば有用と思いますが、そのようなケースは思いつきません。。。

以上です。

コメントを残す