資料庫:Seeding

簡介

在 Laravel 中,我們可以使用 Seed 類別來為資料庫提供初始資料。Seed 類別存放在 database/seeders 目錄中。預設情況下,Laravel 中已定義了一個 DatabaseSeeder 類別。在這個類別中,我們可以呼叫 call 方法來執行其他 Seed 類別,好讓我們能控制資料填充的順序。

lightbulb

在進行 Seeder 時,會自動禁用大量賦值保護

撰寫 Seeder

若要產生 Seeder,請執行 make:seeder Artisan 指令。Laravel 所產生的所有 Seeder 都會放在 database/seeders 目錄下:

1php artisan make:seeder UserSeeder
1php artisan make:seeder UserSeeder

Seeder 類別中預設只包含了一個方法:run。執行 db:seed Artisan 指令 時,會呼叫該方法。在 run 方法中,我們可以任意將資料寫入資料庫內。我們可以使用 Query Builder 來手動寫入資料,或是使用 Eloquent Model Factory 來寫入資料。

來看看一個範例,讓我們來修改預設的 DatabaseSeeder 類別,並在 run 方法內新增一個資料庫 Insert 陳述式:

1<?php
2 
3namespace Database\Seeders;
4 
5use Illuminate\Database\Seeder;
6use Illuminate\Support\Facades\DB;
7use Illuminate\Support\Facades\Hash;
8use Illuminate\Support\Str;
9 
10class DatabaseSeeder extends Seeder
11{
12 /**
13 * Run the database seeders.
14 *
15 * @return void
16 */
17 public function run()
18 {
19 DB::table('users')->insert([
20 'name' => Str::random(10),
21 'email' => Str::random(10).'@gmail.com',
22 'password' => Hash::make('password'),
23 ]);
24 }
25}
1<?php
2 
3namespace Database\Seeders;
4 
5use Illuminate\Database\Seeder;
6use Illuminate\Support\Facades\DB;
7use Illuminate\Support\Facades\Hash;
8use Illuminate\Support\Str;
9 
10class DatabaseSeeder extends Seeder
11{
12 /**
13 * Run the database seeders.
14 *
15 * @return void
16 */
17 public function run()
18 {
19 DB::table('users')->insert([
20 'name' => Str::random(10),
21 'email' => Str::random(10).'@gmail.com',
22 'password' => Hash::make('password'),
23 ]);
24 }
25}
lightbulb

run 方法的簽章 (Signature) 中,我們可以 Type-Hint(型別提示) 任何需要的相依性。Laravel 的 Service Container 會自動解析 Type-Hint 中的相依性。

使用 Model Factory

當然,手動為每個要填入的 Model 指定屬性值是很麻煩的。我們不需要這麼做,而可以使用 Model Factory 來方便地產生大量資料。首先,請先看看 Model Factory 的說明文件以瞭解如何定義 Factory。

舉例來說,我們先來建立 50 個使用者,其中每個使用者都有 1 篇關聯的貼文:

1use App\Models\User;
2 
3/**
4 * Run the database seeders.
5 *
6 * @return void
7 */
8public function run()
9{
10 User::factory()
11 ->count(50)
12 ->hasPosts(1)
13 ->create();
14}
1use App\Models\User;
2 
3/**
4 * Run the database seeders.
5 *
6 * @return void
7 */
8public function run()
9{
10 User::factory()
11 ->count(50)
12 ->hasPosts(1)
13 ->create();
14}

呼叫其他 Seeder

DatabaseSeeder 類別中,我們可以使用 call 方法來執行其他 Seed 類別。使用 call 方法,我們就可以將資料填充的城市拆分成多個檔案,以避免單一 Seeder 類別過於肥大。call 方法接受一組要執行的 Seeder 類別名稱陣列:

1/**
2 * Run the database seeders.
3 *
4 * @return void
5 */
6public function run()
7{
8 $this->call([
9 UserSeeder::class,
10 PostSeeder::class,
11 CommentSeeder::class,
12 ]);
13}
1/**
2 * Run the database seeders.
3 *
4 * @return void
5 */
6public function run()
7{
8 $this->call([
9 UserSeeder::class,
10 PostSeeder::class,
11 CommentSeeder::class,
12 ]);
13}

靜音 Model Event

在進行資料填充時,我們可能會想讓 Model 不要分派 Event。若要防止 Model 分派 Event,可使用 WithoutModelEvent Trait。使用 WithoutModelEvents Trait 時,該 Trait 會確保 Model 不要分派 Event,且也會套用到使用 call 方法執行的 Seed 類別上:

1<?php
2 
3namespace Database\Seeders;
4 
5use Illuminate\Database\Seeder;
6use Illuminate\Database\Console\Seeds\WithoutModelEvents;
7 
8class DatabaseSeeder extends Seeder
9{
10 use WithoutModelEvents;
11 
12 /**
13 * Run the database seeders.
14 *
15 * @return void
16 */
17 public function run()
18 {
19 $this->call([
20 UserSeeder::class,
21 ]);
22 }
23}
1<?php
2 
3namespace Database\Seeders;
4 
5use Illuminate\Database\Seeder;
6use Illuminate\Database\Console\Seeds\WithoutModelEvents;
7 
8class DatabaseSeeder extends Seeder
9{
10 use WithoutModelEvents;
11 
12 /**
13 * Run the database seeders.
14 *
15 * @return void
16 */
17 public function run()
18 {
19 $this->call([
20 UserSeeder::class,
21 ]);
22 }
23}

執行 Seeder

我們可以執行 db:seed Artisan 指令來填充資料庫。預設情況下,db:seed 指令會執行 Database\Seeders\DatabaseSeeder 類別,在該類別內可以進一步叫用其他 Seed 類別。不過,我們也可以使用 --class 選項來個別指定要執行的 Seeder 類別:

1php artisan db:seed
2 
3php artisan db:seed --class=UserSeeder
1php artisan db:seed
2 
3php artisan db:seed --class=UserSeeder

我們也可以使用 migrate:fresh 指令,並搭配 --seed 選項來填充資料。該指令會刪除所有資料表,並重新執行所有的 Migration。若有需要完全重建資料庫,就很適合使用這個指令。--seeder 選項可用來指定執行特定的 Seeder:

1php artisan migrate:fresh --seed
2 
3php artisan migrate:fresh --seed --seeder=UserSeeder
1php artisan migrate:fresh --seed
2 
3php artisan migrate:fresh --seed --seeder=UserSeeder

在正式環境中強制執行 Seeder

有些資料填充的動作是可能會導致資料被修改或消失。為了避免在正式環境資料庫中執行資料填充指令,因此在 production 環境中執行 Seeder 時,會出現提示要求確認。若要強制 Seeder 而不跳出提示,請使用 --force 旗標:

1php artisan db:seed --force
1php artisan db:seed --force
翻譯進度
100% 已翻譯
更新時間:
2023年2月11日 上午10:28:00 [世界標準時間]
翻譯人員:
  • cornch
幫我們翻譯此頁

留言

尚無留言

“Laravel” is a Trademark of Taylor Otwell.
The source documentation is released under MIT license. See laravel/docs on GitHub for details.
The translated documentations are released under MIT license. See cornch/laravel-docs-l10n on GitHub for details.