お問い合わせ
image

Laravel で既存のテーブル構造をコピーする方法

制作・開発
profile

Iftekhar Eather

本記事は、英語で公開されている下記記事の日本語翻訳版です。
How to Copy an Existing Table Structure in Laravel 

はじめに

Laravelを使用していると、既存のテーブルの構造に基づいて、いくつかのカラムを追加した新しいテーブルを作成する必要がある場合があります。Laravelのスキーマビルダーには、あるテーブルから別のテーブルへカラムをコピーする直接的な方法はありませんが、生のSQLクエリを使用することで実現できます。このブログポストでは、既存のテーブルからカラムをコピーして新しいテーブルを作成し、Laravelマイグレーションを使って新しいカラムを追加する方法を説明します。

手順

Step 1: 新しいマイグレーションファイルの作成

まず、新しいマイグレーションファイルを作成する必要があります。以下のArtisanコマンドを実行し、マイグレーションを生成します:

php artisan make:migration create_new_table_name_table

このコマンドはdatabase/migrationsディレクトリに新しいマイグレーションファイルを作成します。

Step 2: マイグレーションファイルの編集

新しく作成されたマイグレーションファイルを開き、既存のテーブルのカラムを取得し、それらのカラムで新しいテーブルを作成するように変更します。以下は、数値を適切に処理する機能が追加された、更新されたマイグレーションファイルです:

<?php
Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateNewTableNameTable extends Migration
{
    public function up()
    {
        $existingTable = 'existing_table_name';
        $newTable = 'new_table_name';

        // Fetch columns from the existing table
        $columns = DB::select("SHOW COLUMNS FROM {$existingTable}");

        // Create the new table with the copied columns
        Schema::create($newTable, function (Blueprint $table) use ($columns) {
            foreach ($columns as $column) {
                $type = $this->getColumnType($column->Type);

                if ($column->Field == 'id') {
                    $table->bigIncrements($column->Field)->default($column->Default);
                } else {
                    $columnType = $this->mapColumnType($type[0], $column);
                    if ($columnType === 'decimal') {
                        $separateValues = explode(',', $type[1]);
                        $table->{$columnType}($column->Field, $separateValues[0], substr($separateValues[1], 0, -1))
                            ->nullable($column->Null == 'NO' ? false : true)
                            ->default($column->Default);
                    } else {
                        $table->{$columnType}($column->Field)->nullable($column->Null == 'NO' ? false : true)
                            ->default($column->Default);
                    }
                }
            }

            // Add new columns
            $table->string('new_column1')->nullable();

            // Usually previous table should have created_at and modified_at , so you can ignore this, otherwise you can add 
            //$table->timestamps();
        });
    }

    /**
     * Get column type from the MySQL type string.
     *
     * @param string $type
     * @return array
     */
    private function getColumnType($type)
    {
        $parts = explode('(', $type);
        return $parts;
    }

    /**
     * Map MySQL column types to Laravel column types.
     *
     * @param string $type
     * @param object $column
     * @return string
     */
    private function mapColumnType($type, $column)
    {
        $typeMapping = [
            'bigint' => 'bigInteger',
            'tinyint' => 'tinyInteger',
            'int' => 'integer',
            'varchar' => 'string',
            'text' => 'text',
            'date' => 'date',
            'datetime' => 'dateTime',
            'timestamp' => 'timestamp',
            'float' => 'float',
            'double' => 'double',
            'decimal' => 'decimal',
//Add more if needed
        ];

        return $typeMapping[$type] ?? 'string';
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('new_table_name');
    }
}
?>

解説

  • 既存のテーブルからのカラムの取得: The SHOW COLUMNS FROM {$existingTable} クエリは、既存のテーブルからカラム定義を取得します。
  • 新しいテーブルの作成: Schema::create メソッドを使用して、コピーされたカラムを持つ新しいテーブルを作成します。カラムは取得したカラム定義を使って動的に追加されます。
  • 数値カラムの処理 : if($columnType==='decimal'){...} ロックは、精度とスケールを指定することで、数値のカラムが正しく扱われるようにします。
  • カラム型のマッピング: mapColumnType メソッドは、MySQLカラムタイプをLaravelカラムタイプにマッピングします。既存のテーブルで使用されている型によっては、このマッピングを拡張する必要があるかもしれません。
  • 新しいカラムの追加: 新しいカラム (new_column1 and new_column2) が新しいテーブルに追加されます。

Step 3: マイグレーションの実行

最後に、マイグレーションを実行して、コピーしたカラムと追加カラムで新しいテーブルを作成します:

php artisan migrate

まとめ

以上の手順で、既存のテーブルの構造に基づいてLaravelで簡単に新しいテーブルを作成し、新しいカラムを追加することができます。この方法は、テーブル構造を動的に複製し、必要に応じて修正する必要がある場合に特に便利です。カラムタイプのマッピングを自由に拡張し、要件に応じた機能を追加してください。
何かあればお気軽にご質問ください。コーディングを楽しんで下さい!