RitoLabo

LaravelのFakerとSeedingでダミーデータを自動生成しデータベースへ投入する

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

開発時にユーザデータや商品情報などのテスト用のデータを用意する必要があったバイに、大量のデータを手作りするのってかなり泣けます(そしてさすがに無理)。手作りでやってもせいぜい10件もいかないくらいがいいところ…プログラマならテストデータを手作りしていてはいけません。

LaravelのFakerというライブラリを使えば、テスト用のフェイクデータを自動で何件でも好きなだけ生成してくれます。
[GitHub]fzaninotto/Faker

今回はマイグレーション実行時にシーディングにて初期データを投入する際に、Fakerにてダミーデータを生成して挿入します。

アジェンダ
  1. 開発環境
  2. モデルクラスの作成
  3. factoryクラスの作成
  4. シーダクラスの編集
  5. マイグレーションからデータベースを再構築する
  6. 自動生成するデータを日本語にする

開発環境

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

  • 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/」とします。

今回はマイグレーションとシーディングを絡めるので、手順を確認したい場合は記事最上部のリンクを参考にしてください。また、データベースの構成も、そこからの流れとなっています。

モデルクラスの作成

まずはモデルを作成します。前回の続きでbooksテーブへの初期投入データを生成する為に、Bookモデルを生成します。

モデル生成の為のartisanコマンドですが、
php artisan make:model [クラス名]
の書式で組み立てます。
ちなみに、テーブル名はbooksだが、モデルクラス名は単数形でつけるのが慣習(テーブル内の1つのレコードに対して操作していくという考え方)なので、ここではBookというモデルクラス名にします。

laravelルートディレクトリから、以下artisanコマンドを叩きモデルクラスを生成します。

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

# モデル生成
php artisan make:model Book

# 実行結果
[demo@localhost laravel]$ php artisan make:model Book
Model created successfully.

laravel/app 配下に Book.php が生成されます。 になります。

laravel
├─ app
  ├─ Book.php

では生成したBookモデルクラスを定義していきます。

laravel/app/Book.php
<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Book extends Model
{
protected $table = 'books';

protected $guarded = array('id');

public $timestamps = true;

protected $fillable = [
'book_name', 'author', 'price', 'stocks', 'release_dt',
];

}

定義自体は基本的な最小の定義になっています。上から説明します。

protected $table = 'books';

テーブル名を定義しています。

protected $guarded = array('id');

AUTO_INCREMENT(オートインクリメント)、いわゆる「主キー」を設定したカラムがある場合には、明示的にここに定義しておきます。

public $timestamps = true;

マイグレーションにて「$table->timestamps();」などして「created_at」「updated_at」カラム(timestamp)を作成している場合には、カラム操作があった場合に自動的に日時を挿入するかを明示的に定義しています。

protected $fillable = [
'book_name', 'author', 'price', 'stocks', 'release_dt',
];

Faker(モデルファクトリ)でのインサートを許可するカラムを定義しています。

factoryクラスの作成

モデルクラスを作成したら、次に生成するデータを定義し、実際に作成して返却するfactoryクラスを作成します。

まずは以下のartisanコマンドを叩いて、factoryクラスを生成します。

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

# モデルファクトリー生成
php artisan make:factory BookFactory

# 実行結果
[demo@localhost laravel]$ php artisan make:factory BookFactory
Factory created successfully.

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

laravel
├─ database
   ├─ factories
      ├─ BookFactory.php

生成した「BookFactory.php」に、生成するデータの定義・返却を記述していきます。

laravel/database/factories/BookFactory.php
<?php

use Faker\Generator as Faker;

/* @var Illuminate\Database\Eloquent\Factory $factory */

$factory->define(App\Book::class, function (Faker $faker) {
return [
'book_name' => $faker->realText($maxNbChars = 20, $indexSize = 1),
'author' => $faker->name,
'price' => $faker->numberBetween($min = 600, $max = 4000),
'stocks' => $faker->numberBetween($min = 1, $max = 100),
'release_dt' => $faker->dateTime($max = 'now', $timezone = date_default_timezone_get()),
];
});

簡単に説明すると、それぞれのカラムに対してどのようなダミーデータを生成するかを定義しているのがここになります。

シーダクラスの編集

最後に、シーダクラスにFakerを使った実装を行っていきます。

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

use Illuminate\Database\Seeder;

class BooksTableSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
factory(App\Book::class, 10)->create();
}
}

factoryメソッドに引数として、Bookモデルと生成する件数(ここでは10件)を指定しています。

マイグレーションからデータベースを再構築する

それでは、マイグレーションからデータベースを再構築し、自動生成データを投入してみます。
laravelのルートディレクトリへ移動し、artisanコマンドを叩きます。

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

# データベースを再構築し、初期投入データを流し込む
php artisan migrate:refresh --seed

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

マイグレーションが完了したら、MySQLにログインしてデータを確認してみます。

mysql> select * from books;
+----+-----------------------------------------------------+----------------------+-------+--------+---------------------+---------------------+---------------------+
| id | book_name | author | price | stocks | release_dt | created_at | updated_at |
+----+-----------------------------------------------------+----------------------+-------+--------+---------------------+---------------------+---------------------+
| 1 | Nihil nam magni pariatur. | Brannon Donnelly | 1445 | 8 | 2007-02-20 02:51:59 | 2017-10-29 02:50:12 | 2017-10-29 02:50:12 |
| 2 | Sit id accusantium autem error ut ut. | Kianna Rodriguez | 849 | 52 | 1975-10-29 04:56:57 | 2017-10-29 02:50:12 | 2017-10-29 02:50:12 |
| 3 | Minima ea quidem dolores ut non. | Narciso Schumm | 705 | 42 | 2002-06-18 04:49:55 | 2017-10-29 02:50:12 | 2017-10-29 02:50:12 |
| 4 | Qui sint pariatur magnam qui quo. | Isai Krajcik DVM | 3749 | 51 | 2005-10-31 21:25:07 | 2017-10-29 02:50:12 | 2017-10-29 02:50:12 |
| 5 | Nesciunt ab sint esse. | Kelsi Nicolas | 1087 | 48 | 2012-08-25 03:40:58 | 2017-10-29 02:50:12 | 2017-10-29 02:50:12 |
| 6 | Nam provident impedit aut cupiditate. | Prof. Rick Rippin | 1768 | 31 | 2002-04-06 16:05:52 | 2017-10-29 02:50:12 | 2017-10-29 02:50:12 |
| 7 | Ullam dolores omnis hic facilis. | Tianna Wisozk | 1126 | 22 | 1995-12-07 06:37:46 | 2017-10-29 02:50:12 | 2017-10-29 02:50:12 |
| 8 | Fuga sit ratione eius ipsam debitis et consequatur. | Terrence Green | 1215 | 3 | 1998-11-15 11:20:49 | 2017-10-29 02:50:13 | 2017-10-29 02:50:13 |
| 9 | Laboriosam similique perferendis explicabo quidem. | Ms. Susana Greenholt | 617 | 49 | 2005-03-25 14:27:41 | 2017-10-29 02:50:13 | 2017-10-29 02:50:13 |
| 10 | Quae non odit ratione autem. | Marion O'Hara DDS | 748 | 77 | 1971-05-11 06:39:55 | 2017-10-29 02:50:13 | 2017-10-29 02:50:13 |
+----+-----------------------------------------------------+----------------------+-------+--------+---------------------+---------------------+---------------------+

きちんと定義した通りのデータが投入されている事が確認できました。

自動生成するデータを日本語にする

Fakerで自動生成されるデータは、デフォルトでは英語です。
日本語のデータを投入したい。ということもあります。それももちろん可能です。その手順をこれから解説します。

まず、Fakerの言語設定(locale)は app.php で管理しているので、そこに記述を行います。当該ファイルの適当な場所に以下を追記します。

laravel/config/app.php
/*
|--------------------------------------------------------------------------
| Faker Setting
|--------------------------------------------------------------------------
*/
'faker_locale' => env('DEV_FAKER_LOCALE', 'en_US'),

次にENVファイルを開き、以下を追記します。

laravel/.env
DEV_FAKER_LOCALE=ja_JP

再度マイグレーションでデータベースを再構築しデータを投入します。

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

# データベースを再構築し、初期投入データを流し込む
php artisan migrate:refresh --seed

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

MySQLにログインして結果を確認してみます。

mysql> select * from books;
+----+-------------------------------------+---------------+-------+--------+---------------------+---------------------+---------------------+
| id | book_name | author | price | stocks | release_dt | created_at | updated_at |
+----+-------------------------------------+---------------+-------+--------+---------------------+---------------------+---------------------+
| 1 | 出たりょうだけて立っていとまいって、と。 | 西之園 直樹 | 1036 | 18 | 2008-05-02 20:30:39 | 2017-10-29 12:53:55 | 2017-10-29 12:53:55 |
| 2 | おちょうはどもひょうに降お父さそしたた。 | 近藤 聡太郎 | 3365 | 85 | 1988-02-10 19:19:13 | 2017-10-29 12:53:55 | 2017-10-29 12:53:55 |
| 3 | トようかぎを見つまざっしたがそい出しょ。 | 山口 結衣 | 1109 | 54 | 2005-06-11 01:08:43 | 2017-10-29 12:53:55 | 2017-10-29 12:53:55 |
| 4 | たと鷺させい立って来てまってあそれて立。 | 伊藤 真綾 | 3365 | 15 | 1986-06-23 02:12:05 | 2017-10-29 12:53:55 | 2017-10-29 12:53:55 |
| 5 | ど深ふくじからんどのがた。このようしく。 | 村山 英樹 | 2362 | 40 | 1998-12-31 20:16:28 | 2017-10-29 12:53:55 | 2017-10-29 12:53:55 |
| 6 | を組ますれは帽子が、そうちまっと白くの。 | 渚 七夏 | 3738 | 51 | 1980-09-12 20:08:34 | 2017-10-29 12:53:55 | 2017-10-29 12:53:55 |
| 7 | 子供こらなんした。「ジョバンニにしたっ。 | 田中 智也 | 3293 | 34 | 1997-04-26 23:50:51 | 2017-10-29 12:53:55 | 2017-10-29 12:53:55 |
| 8 | べるのですかみん、雑誌ざとりと同級ども。 | 斉藤 七夏 | 1914 | 89 | 1970-03-26 20:24:13 | 2017-10-29 12:53:56 | 2017-10-29 12:53:56 |
| 9 | し前の生がらしていやぶえたちょう、水晶。 | 三宅 浩 | 1006 | 19 | 1977-01-22 23:34:40 | 2017-10-29 12:53:56 | 2017-10-29 12:53:56 |
| 10 | 服ふいしかりもつるいまずうに立って行っ。 | 井上 陽子 | 974 | 72 | 1998-08-19 09:43:39 | 2017-10-29 12:53:56 | 2017-10-29 12:53:56 |
+----+-------------------------------------+---------------+-------+--------+---------------------+---------------------+---------------------+

日本語でデータが投入されている事が確認できました。

まとめ

作業は以上で完了です。factoryクラスに記述するデータの定義についてもっと知りたい場合は、冒頭で紹介した公式のGitHubを見てみてください。かなり多くのデータ定義が可能です。(メアドや電話番号、住所や銀行口座などまで作ってくれます。)

テストデータを用意するのは本当に骨が折れるのですが、Fakerを使えばたとえ10万件だろうが簡単に作成できます。是非試してみてください。