RitoLabo

LaravelのSeeding(シーディング)でデータベースへ任意の初期データを自動投入する

  • 公開:
  • 更新:
  • カテゴリ: PHP Laravel
  • タグ: PHP,Laravel,migration,Seeding,5.5,5.4,5.3,5.6

Laravelには、「シーダクラス(初期値設定クラス)」というものがあり、データベースへ初期データを簡単に投入できます。

例えば、マイグレーションでデータベースを構築し、シーディングで初期データを投入するようにしておけば、いつでもデータベースの再構築と初期データの投入までを行えます。

一人で開発している場合でも十分に役に立つのですが、チームで開発する場合にはさらに力を発揮するのもこのシーディングです。マイグレーションとシーディングを設定しておけば、チームに新しいメンバーがアサインした場合でも、artisanコマンドを叩くだけで一撃で必要なデータベースと初期データが提供できます。

マイグレーションに関しては以下の解説を参照してください。
Laravelのマイグレーション&スキーマビルダでDBのテーブルやカラムを作成する
今回は、シーディングについて解説していきます。

今回の環境は以下の通りです。

  • linux CentOS 7
  • Apache 2.4
  • MySQL 5.7
  • PHP 7.2/7.1
  • Laravel

Laravelのバージョンに関しては5.6/5.5/5.4/5.3にて動作確認済みです。

Laravelのルートディレクトリを「laravel/」とします。

linux環境ではなくXAMPPでも、artisanコマンドが使えれば同様の手順で進めていけます。

アジェンダ
  1. Seedファイルの生成
  2. シーダークラスの定義
  3. シーダクラスをコールする為の設定
  4. シーディング実行
  5. マイグレーションとシーディングでデータベースを再構築する

Seedファイルの生成

まずは、投入するデータを記述するためのSeedファイルを生成します。その為にまずは、にシーダクラス名を決めます。

公式に倣うのであれば、「"TABLEBNAME"TableSeeder」のような名前が良いです。ここでは、本の管理テーブルである「books」へのシーダーを生成するので、「BooksTableSeeder」という名前にします。

クラス名が決まったら、Laravelルートディレクトリに移動し、シーダー生成の為の以下のartisanコマンドを叩きます。

# laravelルートディレクトリへ移動
cd /path/to/laravel

# シーダー生成のためのartisanコマンドを叩く
php artisan make:seeder BooksTableSeeder

# 実行結果
[demo@localhost laravel]$ php artisan make:seeder BooksTableSeeder
Seeder created successfully.

laravel/database/seeds 配下に BooksTableSeeder.phpが生成されます。

laravel
├─ database
│ ├─ seeds
│ │ ├─
BooksTableSeeder.php

シーダーの生成が完了したら、ファイルを確認します。

シーダークラスの定義

それでは生成したシーダークラスを定義(データを流し込む記述)していきます。先ほど生成したシーダファイルを開きます。

laravel/database/seeds/BooksTableSeeder.php
<?php

use Illuminate\Database\Seeder;

class BooksTableSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
//
}
}

このrun()メソッドにデータを投入する記述を行います。

laravel/database/seeds/BooksTableSeeder.php
<?php

use Illuminate\Database\Seeder;

class BooksTableSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
DB::table('books')->insert([
[
'book_name' => 'ブック1',
'author' => '著者1',
'price' => 1000,
'stocks' => 20,
'release_dt' => date('Y-m-d H:i:s'),
],
[
'book_name' => 'ブック2',
'author' => '著者2',
'price' => 2000,
'stocks' => 30,
'release_dt' => date('Y-m-d H:i:s'),
],
[
'book_name' => 'ブック3',
'author' => '著者3',
'price' => 1200,
'stocks' => 150,
'release_dt' => date('Y-m-d H:i:s'),
],
]);
}
}

シンプルに、DBファサードを使ってクエリビルダでインサートを実装している。という事になります。

シーダクラスをコールする為の設定

シーダクラスの定義が完了したら、このシーダクラスをシーディング実行時にコール(呼び出す)できるようにします。seedsディレクトリにあるもう一つのファイルDatabaseSeeder.phpに以下を記述します。

laravel/database/seeds/DatabaseSeeder.php
<?php

use Illuminate\Database\Seeder;

class DatabaseSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
$this->call([
BooksTableSeeder::class,
]);
}
}

ここにクラスを登録することにより、シーディング実行時にクラスがコールされ、実行されます。また、登録したいシーダクラスが複数ある場合には、この配列に追加していけばOKです。

シーディング実行

それでは実際にシーディングを実行してみます。Laravelルートディレクトリに移動し、以下を叩きます。

# laravelルートディレクトリへ移動
cd /path/to/laravel

# シーダー実行のartisanコマンドを叩く
php artisan db:seed

# 実行結果
[demo@localhost laravel]$ php artisan db:seed
Seeding: BooksTableSeeder

実行が完了したら、実際にMySQLへログインしてデータを確認してみます。

mysql> select * from books;
+----+--------------+-----------+-------+--------+---------------------+------------+------------+
| id | book_name | author | price | stocks | release_dt | created_at | updated_at |
+----+--------------+-----------+-------+--------+---------------------+------------+------------+
| 1 | ブック1 | 著者1 | 1000 | 20 | 2017-10-28 10:11:01 | NULL | NULL |
| 2 | ブック2 | 著者2 | 2000 | 30 | 2017-10-28 10:11:01 | NULL | NULL |
| 3 | ブック3 | 著者3 | 1200 | 150 | 2017-10-28 10:11:01 | NULL | NULL |
+----+--------------+-----------+-------+--------+---------------------+------------+------------+

問題なく初期データが投入されている事を確認できました。

マイグレーションとシーディングでデータベースを構築する

マイグレーションをロールバックした場合に、もちろんデータも一緒に失われてしまうわけですが、ロールバック&再構築の際には、以下のコマンドを叩く事でロールバック(定義したテーブル全削除)→テーブル再構築→シーディング実行(初期データ投入)までを1つのコマンドで行えます。

# マイグレーションにて全ロールバックを行い、テーブル再構築の後、シーディングを実行(初期データ投入)する
php artisan migrate:refresh --seed

# 実行結果
[demo@localhost laravel]$ php artisan migrate:refresh --seed
Rolling back: 2018_05_21_223549_create_books_table
Rolled back: 2018_05_21_223549_create_books_table
Migrating: 2018_05_21_223549_create_books_table
Migrated: 2018_05_21_223549_create_books_table
Seeding: BooksTableSeeder

実行結果を見ると、まずロールバック(削除)が行われ、そしてマイグレート(再構築)し、最後にシーディング(初期データ投入)が行われているのがわかります。

ちなみに初回実行の場合は単純に、マイグレーション実行時にシーダー実行のオプションをつけたartisanコマンドを叩けばOKです

# laravelルートディレクトリへ移動
cd /path/to/laravel

# マイグレーション実行時にシーダー実行のオプションをつけたartisanコマンドを叩く
php artisan migrate --seed

# 実行結果
[demo@localhost laravel]$ php artisan migrate --seed
Migrating: 2018_05_21_223549_create_books_table
Migrated: 2018_05_21_223549_create_books_table
Seeding: BooksTableSeeder

まとめ

以上で作業は完了です。シーディングとマイグレーションの組み合わせは最強ですが、もちろんシーディングだけでも使う事が出来ますので、是非試してみてください。

また、今回はシンプルにシーダクラスに手動でインサートするデータを記述しましたが、自動でランダムにデータを生成して投入する方法もあります。次回はその手順について解説します。

next:LaravelのFakerとSeeding(シーディング)を使い、テスト(フェイク)データを自動生成しデータベースへ投入する