LaravelのSeeding機能を利用してダミーデータを一括挿入
Laravel6.x, Laravel5.8, 5.7で動作確認済み。また一部Laravel8でのSeedingの方法も説明しています。
テスト環境での機能確認、コードの動作確認を行うためにテーブルに大量のテストデータが必要になる場合があります。手動や自作のプログラムを作ることなく一括で大量のデータを挿入することができると作業の効率化に繋がります。LaravelではSeedingという機能が準備されておりSeeding機能を使用することで、大量のダミーデータを一括でテーブルに挿入することが可能です。
目次
Seedingの設定について
Laravelでは、usersテーブルへのダミーデータを挿入するSeedingの設定はインストール直後の段階で90%以上完了していますがSeedingについてはLaravelのマニュアルを読んでも最初は混乱するかもしれません。しかし一度usersテーブルを利用してSeedingを実行してみると操作方法をすぐに理解することができます。一度自分の手で実行することがSeedingを理解する上で一番の近道です。
動作確認を行うためには、Laravelのインストールだけではなくデータベースの中にusersテーブルが作成されている必要があります。もしデータベースが未作成の場合は、sqliteを使うと簡単にテスト用のデータベース環境を構築することができます。
Laravel8でusersテーブルにダミーデータ挿入
Laravel8の環境であればusersテーブルへのダミーデータの挿入は驚くほど簡単に行うことができます。
database¥seeders¥DatabaseSeeder.phpファイルを開いて、runメソッドに入っているコメントを削除します。
namespace Database\Seeders;
use Illuminate\Database\Seeder;
class DatabaseSeeder extends Seeder
{
public function run()
{
\App\Models\User::factory(10)->create(); //この行のコメントを外す
}
}
コメントを外し、php artisan db:seedコマンドを実行するだけでusersテーブルに10件のダミーデータが保存されます。
% php artisan db:seed
Database seeding completed successfully.
なにかダミーデータを利用して動作確認したい場合は簡単に行うことができますね。
ダミーデータ挿入までの流れ
ダミーデータの挿入方法には1件のみ挿入する方法と一括挿入する方法があります。処理の違いは、UserFactory.phpを使うか使わないかの違いです。1件のデータ挿入は効率化には繋がりませんが、説明は行なっておきます。
usersテーブルの場合は、Laravel側で事前に設定がなされているのでダミーデータを挿入する場合処理は数秒で完了しますが複数のファイルを利用することになるので混乱しないように先に流れを簡単にまとめておきます。
1件だけのダミーデータ挿入
- Seederクラスの作成
- UserTableSeederクラスのrunメソッドの更新
- DabaseSeedの設定
- Seedの実行
複数のダミーデータ一括挿入
- Seederクラスの作成
- UserTableSeederクラスのrunメソッドの更新
- UserFactory.phpファイルの更新
- DabaseSeedの設定
- Seedの実行
Seederクラスの作成
ダミーデータを作成するためには、ダミーデータを作成するクラスを作成する必要があります。そのクラスのことをLaravelではSeederと呼びます
php artisan make:seederコマンドでSeederの作成を行います。
laravel $ php artisan make:seeder UsersTableSeeder
Seeder created successfully.
make:seederコマンドを実行するとUsersTableSeederクラスがdatabase/seedsディレクトリに作成されます。
Seederクラスのrunメソッドの設定
Seederクラスには、insert文を直接記述する方法とUserFactory.phpを呼び出して一括でダミーデータを挿入する方法があります。通常は一括でのダミーデータだとは思いますが、処理方法が少し異なるので実行したい方法を選択して進んでください。
1件のデータのみ挿入する場合
UserTableSeederクラスのrunメソッドにデータベースへのinsert文を直接記述します。
use Illuminate\Database\Seeder;
class UsersTableSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
DB::table('users')->insert([
'name' => Str::random(10),
'email' => Str::random(10).'@gmail.com',
'password' => bcrypt('secret'),
]);
}
}
name, e-mailには、Strクラスのrandomメソッドを利用してその都度ランダムな10桁の文字列を作成しています。passwordはbcrypt関数でsecretの文字列を暗号化しています。nameやe-mailは任意の文字列をハードコーディングすることもできます。
複数のデータを一括挿入
UsersTableSeederクラスのrunメソッドに下記の1行を追加します。この1行を追加することによって、UsersTableSeederのrunメソッドが実行されるとUserテーブルにダミーデータ10件分が挿入されます。10を20に変更すれば20件のデータ挿入になります。
<?php
use Illuminate\Database\Seeder;
class UsersTableSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
$users = factory(App\User::class, 10)->create();
}
}
上記だけのプログラムではダミーデータに何を入れるのかが設定されていません。Seederではそれらのデータの設定も行うことができます。その設定を行うのが次に説明するUserFactory.phpファイルです。
UserFactory.phpファイルはテンプレートとしてLaravelで事前準備されています。
UserFactory.phpファイル(Model Factory)
1件のデータのみ挿入する場合を選択し、UserTableSeederクラスでのinsert文を使用した場合は下記の文章はスキップしてDatabaseSeederの設定に進んでください。
$users = factory(User::class, 10)->create()で実行される処理の内容は、database/factoriesディレクトリにあるUserFactory.phpに記載されています。UserFactory.phpはfakerやランダム関数等を利用して、ダミーのデータを作成するクラスです。このクラスのことをModel Factory(モデルファクトリー)と呼びます。
<?php
use Faker\Generator as Faker;
$factory->define(User::class, function (Faker $faker) {
return [
'name' => $faker->name,
'email' => $faker->unique()->safeEmail,
'email_verified_at' => now(),
'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', // password
'remember_token' => Str::random(10),
];
});
DatabaseSeederの設定
作成したUserTableSeederクラスを呼び出すDatabaseSeederの設定を行います。DatabaseSeeder.phpファイルは、database/seedsディレクトリにあります。runメソッドがインストール直後ではコメントアウトされているので、それを外します。
<?php
use Illuminate\Database\Seeder;
class DatabaseSeeder extends Seeder
{
/**
* Seed the application's database.
*
* @return void
*/
public function run()
{
$this->call(UsersTableSeeder::class);
}
}
Seedの実行
ダミーデータを作成するための準備が整ったので、php artisan db:seedコマンドを実行します。コマンド実行後にプログラムに誤りがなければUsersTableSeederが実行され、seedingが成功しているメッセージが表示されます。
laravel $ php artisan db:seed
Seeding: UsersTableSeeder
Database seeding completed successfully.
テーブルを再作成する際にダミーデータを挿入することもできます。その場合は、php artisan migrate:refreshコマンドに–seedをつけて実行します。refreshコマンドは一度すべてのテーブルを削除するのでテスト環境でのみ実行してください。本番環境で実行するとこれまでに保存してデータも削除されます。
$ php artisan migrate:refresh --seed
Rolling back: 2019_08_19_000000_create_failed_jobs_table
Rolled back: 2019_08_19_000000_create_failed_jobs_table (0.01 seconds)
Rolling back: 2014_10_12_100000_create_password_resets_table
Rolled back: 2014_10_12_100000_create_password_resets_table (0 seconds)
Rolling back: 2014_10_12_000000_create_users_table
Rolled back: 2014_10_12_000000_create_users_table (0 seconds)
Migrating: 2014_10_12_000000_create_users_table
Migrated: 2014_10_12_000000_create_users_table (0 seconds)
Migrating: 2014_10_12_100000_create_password_resets_table
Migrated: 2014_10_12_100000_create_password_resets_table (0 seconds)
Migrating: 2019_08_19_000000_create_failed_jobs_table
Migrated: 2019_08_19_000000_create_failed_jobs_table (0 seconds)
Seeding: UsersTableSeeder
Seeded: UsersTableSeeder (0.15 seconds)
Database seeding completed successfully.
データが挿入されたかどうか確認するためにtinkerを利用します。10件分のユーザ情報が表示されればSeedingは正常に動作しています。
$ php artisan tinker
Psy Shell v0.9.9 (PHP 7.2.21 — cli) by Justin Hileman
>>> $user = App\User::all();
=> Illuminate\Database\Eloquent\Collection {#3012
all: [
App\User {#3013
id: "1",
name: "Miss Mathilde Buckridge V",
email: "arnaldo.prohaska@example.com",
email_verified_at: "2019-10-23 05:14:25",
created_at: "2019-10-23 05:14:25",
updated_at: "2019-10-23 05:14:25",
Seedingの一連の流れ
php artisan db:seedを実行するSeedingに関連するファイルを図にすると下記となります。
本文書で利用したファイルは、DatabaseSeeder.php、UserTableSeeder.php, UserFactory.phpの3つのファイルです。userテーブルだけではなく、他のテーブル(例えばpostテーブル)にもダミーデータを挿入したい場合は、PostTableSedder.phpやPostFactory.phpを作成し、DatabaseSeeder.phpからPostTableSeeder.phpを呼び出すことで行うことができます。
リレーションのあるテーブルへの挿入
ここまでの説明で1つのテーブルへのデータ挿入の確認を行うことができました。次にテーブル間で1対多のリレーションがある場合の設定について説明を行っていきます。
postsテーブルの作成
例としてブログの記事を登録するpostsテーブルを作成します。ブログの記事にはだれがその記事を作成したかテーブルの中に保存する必要があります。ブログでは一人のユーザが複数の記事を書くのでテーブルの関連を図に表すと下記のようになります。この関係をデータベースではone to manyリレーションシップといいます。
postsテーブルはマイグレーションファイルを利用して作成します。make:modelコマンドを実行するとappディレクトリの下にPost.phpファイル、database¥migrationsテーブルの下にpostテーブルのマイグレーションファイルが作成されます。
$ php artisan make:model Post -m
マイグレーションファイルに作成するテーブルの列情報を記述します。user_id列にusersテーブルのidを保存するためにpostsテーブルにはuser_idの列を作成します。
public function up()
{
Schema::create('posts', function (Blueprint $table) {
$table->bigIncrements('id');
$table->unsignedInteger('user_id');
$table->string('title');
$table->text('content');
$table->timestamps();
});
}
マイグレーションファイルが作成できたら、php artisan mirgateコマンドを使ってpostsテーブルの作成を行います。
$ php artisan migrate
Migrating: 2019_10_23_053953_create_posts_table
Migrated: 2019_10_23_053953_create_posts_table (0 seconds)
Seederクラスの作成
postsテーブル用のseederクラスの作成を行います。実行するとdatabase¥seedsディレクトリにPostsTableSeeder.phpファイルが作成されます。
$ php artisan make:seeder PostsTableSeeder
Seeder created successfully.
PostsTableSeeder.phpファイルでは10件分をデータを一括で挿入する設定を行います。
<?php
use Illuminate\Database\Seeder;
class PostsTableSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
$posts = factory(App\Post::class, 10)->create();
}
}
Factoryファイルの作成
usersテーブルのFactoryファイルはLaravelのインスールで事前に作成されていましたが、postsテーブルの場合はFactoryファイルを作成する必要があります。作成は下記のコマンドmake:factoryで行います。
$ php artisan make:factory PostFactory -m Post
Factory created successfully.
database¥factoriesの下にPostFactory.phpが作成されるので下記のように作成するダミーデータに関する設定を行います。ポイントはuser_idにidを挿入するためUserのFactoryを使用してuserのデータも同時に作成しています。
<?php
/* @var $factory \Illuminate\Database\Eloquent\Factory */
use App\Post;
use Faker\Generator as Faker;
$factory->define(Post::class, function (Faker $faker) {
return [
'title' => $faker->title,
'content' => $faker->paragraph,
'user_id' => function () {
return factory(App\User::class)->create()->id;
}
];
});
これで1対多のリレーションを持ったテーブルへのデータ挿入の設定ができました。
DatabaseSeederの設定
最後にdatabase¥seeds¥DatabaseSeeders.phpファイルを下記のように変更します。userに関するデータ作成はPostFactory.phpで行われているので、UsersTableSeederの設定の行は必要ありません。
public function run()
{
$this->call(PostsTableSeeder::class);
}
Seederの実行
postsテーブルへのダミーデータ一括登録の準備が整ったので、seederを実行します。メッセージにDatabase seeding completed successfully.が表示されればテーブルへのデータ登録は完了しています。
env_test $ php artisan db:seed
Seeding: PostsTableSeeder
Database seeding completed successfully.
ダミーデータが作成されたかの確認
postsテーブルにダミーデータが10件登録されているのか確認してみましょう。php artisan tinkerを使用します。データが表示されれば、Seedingの処理は成功です。
$ php artisan tinker
Psy Shell v0.9.9 (PHP 7.2.21 — cli) by Justin Hileman
>>> $post = App\Post::all();
=> Illuminate\Database\Eloquent\Collection {#3012
all: [
App\Post {#3013
id: "1",
user_id: "1",
title: "Prof.",
content: "Nam aliquam repudiandae hic eos. Laboriosam ut vero nihil quas. Cumque ullam earum temporibus voluptate. Eaque rerum suscipit ut rerum.",
created_at: "2019-10-23 05:48:21",
updated_at: "2019-10-23 05:48:21",
},
user_idには1が入っているので、App\User::find(1)を実行すると取得することができます。
>>> App\User::find(1);
=> App\User {#2998
id: "1",
name: "Marielle Kuhlman",
email: "schmeler.deion@example.net",
email_verified_at: "2019-10-23 05:48:21",
created_at: "2019-10-23 05:48:21",
updated_at: "2019-10-23 05:48:21",
}
付録
日本語のダミーデータ作成
ダミーで作成されていたユーザ名はすべて英語になっていましたが、日本語に変更することもできます。
config/app.phpファイル内にfaker_localeを設定する箇所があるので、ja_JPに変更すると日本語になります。
'faker_locale' => 'ja_JP',
php artisan tinkerを使用してダミーデータ作成
UserFactory.phpファイルの作成が完了していたら、php artisan tinkerからダミーデータを作成することが可能です。
$ php artisan tinker
Psy Shell v0.9.9 (PHP 7.1.23 — cli) by Justin Hileman
>>> factory('App\User',10)->create();
=> Illuminate\Database\Eloquent\Collection {#2997
all: [
App\User {#2993
name: "田中 淳",
email: "naoko22@example.net",
email_verified_at: "2019-06-12 05:22:10",
updated_at: "2019-06-12 05:22:10",
created_at: "2019-06-12 05:22:10",
id: 1,
}
その他のダミーデータ
本文書では、users, postsテーブルにダミーデータを挿入するため、name, safeEmail, title, paragraphを利用しました。これ以外にもたくさんのダミーデータが準備されています。他のダミーデータについてはvendor¥fzaninotto¥faker¥src¥Faker¥Generator.phpファイルで確認することができます。
一部紹介しておきます。
- firstName
- firatNameMale
- firstNameFemale
- lastName
- title
- city
- postcode
- address
- country
- companyEmail
- colorName
まとめ
ここまでの読み進めた方はuserテーブルへのダミーデータへの挿入とone to manyのリレーショップのあるテーブルへのダミーデータへの挿入は理解できたかと思います。