本記事は、英語で公開されている下記記事の日本語翻訳版です。
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_column1andnew_column2) が新しいテーブルに追加されます。
Step 3: マイグレーションの実行
最後に、マイグレーションを実行して、コピーしたカラムと追加カラムで新しいテーブルを作成します:
php artisan migrate
まとめ
以上の手順で、既存のテーブルの構造に基づいてLaravelで簡単に新しいテーブルを作成し、新しいカラムを追加することができます。この方法は、テーブル構造を動的に複製し、必要に応じて修正する必要がある場合に特に便利です。カラムタイプのマッピングを自由に拡張し、要件に応じた機能を追加してください。
何かあればお気軽にご質問ください。コーディングを楽しんで下さい!