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

公開
更新
注意最終更新から 7 年以上経過しています。最新の情報もあわせてご確認ください。

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

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

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

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

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

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

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

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

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

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 です。

オートローダ再生成

最後に Composer のオートローダを再生成します。以下の Composer コマンドを叩きます。

# autoloader 再生成
composer dump-autoload

シーディング実行

それでは実際にシーディングを実行してみます。 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(シーディング)を使い、テスト(フェイク)データを自動生成しデータベースへ投入する

Ritolabo