laravel 資料庫 Seeder 練習

@ver 0.1.2 @date 2019-03-20 21:24:27 (星期三)

@ver 0.1.1 @date 2019-03-18 10:37:11 (星期一)

seeding 參考(繁體中文 資料庫 : 資料填充)

seeding 參考(簡體中文 数据填充)

  1. Seeder 資料庫資料填充

    資料庫資料填充, 就是用 artisan 在資料表產生預設數據.

    完成了上一節的 Auth 實作, 我們必須進入網頁去實際填寫一些資料, 才能新增一位 User 到資料庫. 有時只是要測試程式邏輯或 Model , 花一些時間作一個 Form 來填寫資料再新增至資料庫, 相當不划算. 還有些狀況是要預設一些值到資料庫裡給後續工作使用, 這時候就需要 Seeder 來幫忙.

    繼續上一個專案 testAuth

    建立 Seeder Class

    Seeder 程式要自行建立, 會放到 database/seeds/ 目錄下

    命令

    php artisan make:seeder UsersTableSeeder
    git st -s

    執行結果

    [alex@nvda ~/jobs/testAuth ]$ php artisan make:seeder UsersTableSeeder
    Seeder created successfully.
    [alex@nvda ~/jobs/testAuth ]$ git st -s
    ?? database/seeds/UsersTableSeeder.php
    [alex@nvda ~/jobs/testAuth ]$

    直接產生一個 database/seeds/UsersTableSeeder.php 檔案, 編輯這個檔案, 在 run() 函數裡加上要產生的 user 欄位資料, 可以只寫必填資料. 我使用 DB:: 跟 Factory() 兩種方式產生.

    UsersTableSeeder.php 程式碼

    public function run()
    {
        // create a demo user
        DB::table('users')->insert([
            'name' => '測試帳號1',
            'email' => 'a@b.com',
            'password' => bcrypt('hello'),
        ]);
        $user = Factory(App\User::class)->create([
            'name' => '測試帳號2',
            'email' => 'b@c.com',
            // factory default password is 'password'
        ]);
    }

    原本的 database/seeds/DatabaseSeeder.php 檔案, 編輯這個檔案, 在 run() 函數裡加入上面的 Seeder 類別名稱, 用來呼叫產生資料, 若是有多個 Seeder 類別就用陣列.

    DatabaseSeeder.php 程式碼

    public function run()
    {
        $this->call(UsersTableSeeder::class);
        // 多個 Seeder 類別就用陣列 // $this->call([UsersTableSeeder::class, ...]);
    }

    完成 Seeder 類別的編寫之後,需要使用 dump-autoload 命令重新產生 Composer 的自動載入程式, 否則會抓不到 UsersTableSeeder 這個 class

    命令

    composer dump-autoload

    執行結果

    [alex@nvda ~/jobs/testAuth ]$ composer dump-autoload
    Generating optimized autoload files> Illuminate\Foundation\ComposerScripts::postAutoloadDump
    > @php artisan package:discover --ansi
    Discovered Package: beyondcode/laravel-dump-server
    Discovered Package: fideloper/proxy
    Discovered Package: laravel/tinker
    Discovered Package: laravelcollective/html
    Discovered Package: nesbot/carbon
    Discovered Package: nunomaduro/collision
    Discovered Package: spatie/laravel-permission
    Package manifest generated successfully.
    Generated optimized autoload files containing 3552 classes
    [alex@nvda ~/jobs/testAuth ]$

    產生 seed

    有好幾種方式可以產生 seed, 只做 seed 或選擇清空資料庫重新建立並 seed, 下列命令請自選一個

    命令

    # 全部 seed
    php artisan db:seed
    # 或指定某一個資料表 seed
    php artisan db:seed --class=UsersTableSeeder
    # 或清空資料庫重新建立並 seed
    php artisan migrate:fresh --seed

    執行結果

    [alex@nvda ~/jobs/testAuth ]$ php artisan db:seed
    Seeding: UsersTableSeeder
    Database seeding completed successfully.
    [alex@nvda ~/jobs/testAuth ]$

    查看資料表 users, 這 2 筆就程式碼裡的設定, 現在可以進去網頁, 試著用這 2 個 email 登入, 注意他們的密碼不同.

    執行結果

    mysql> select id,name,email from users;
    +----+---------------+---------+
    | id | name          | email   |
    +----+---------------+---------+
    |  1 | 測試帳號1     | a@b.com |
    |  2 | 測試帳號2     | b@c.com |
    +----+---------------+---------+
    2 rows in set (0.00 sec)

    工廠大量生產

    上面我們用了 DB::table('users')->insert([...]);Factory(App\User::class)->create([...]) 在 seed 時, 自動產生一筆預設的資料, 但萬一, 人生總是會有萬一, 寫程式也是. 需要一次大量產生數百數千筆資料來測試或其他應用時, 此刻就需要工廠來自動化幫我們大量生產假的測試資料, 再度修改 database/seeds/UsersTableSeeder.php 檔案, 在原先 run() 函數結束前再加一行 factory(App\User::class, 6)->create(); 自動產生 6 筆假的測試 users, 如下

    UsersTableSeeder.php 程式碼

    public function run()
    {
        // create a demo user
        DB::table('users')->insert([
            'name' => '測試帳號1',
            'email' => 'a@b.com',
            'password' => bcrypt('hello'),
        ]);
        $user = Factory(App\User::class)->create([
            'name' => '測試帳號2',
            'email' => 'b@c.com',
            // factory default password is 'password'
        ]);
        // 原先 run() 函數結束前再加一行 factory() 自動產生 6 筆 users
        factory(App\User::class, 6)->create();
    }

    工廠程式也要對照加上我們要讓它大量生產假資料的欄位值, 先加入 name, email, email_verified_at, password, remember_token 這幾個欄位

    database/factories/UserFactory.php 程式碼

    use App\User;
    ...
    ...
    ...
    $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),
        ];
    });

    命令

    php artisan db:seed

    出現錯誤訊息

    執行結果

    [alex@nvda ~/jobs/testAuth ]$ php artisan db:seed
    Seeding: UsersTableSeeder
    
       Illuminate\Database\QueryException  : SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry 'a@b.com' for key 'users_email_unique' (SQL: insert into `users` (`name`, `email`, `password`) values (測試帳號1, a@b.com, $2y$10$6XkZS7tyQCPspaf1B5XjbujI6zmxhpRE.ViZ8bN5sWLzJg5dE7Kdu))

    因為 users 的 email 欄位, 設定為 unique, 所以先前已建立的會衝突, 可以手動去資料庫刪除先前的兩筆, 或直接清空資料庫重新建立並 seed

    命令 : 清空資料庫重新建立並 seed

    php artisan migrate:fresh --seed

    查看資料表 users, 會有 8 筆, 前 2 筆是原先的設定, 後 6 筆是用工廠自動化生產的假訊息

    執行結果

    mysql> select id,name,email from users;
    +----+---------------------+-----------------------------------+
    | id | name                | email                             |
    +----+---------------------+-----------------------------------+
    |  1 | 測試帳號1            | a@b.com                           |
    |  2 | 測試帳號2            | b@c.com                           |
    |  3 | Mr. Theron Schumm   | jamaal66@example.org              |
    |  4 | Stanton Goldner     | gerard21@example.com              |
    |  5 | Lola Effertz Sr.    | farrell.aidan@example.com         |
    |  6 | Cary Erdman         | heathcote.jacinthe@example.com    |
    |  7 | Mr. Columbus Crooks | pinkie79@example.org              |
    |  8 | Ofelia Lubowitz     | rozella.runolfsdottir@example.org |
    +----+---------------------+-----------------------------------+
    8 rows in set (0.00 sec)
    
    mysql>

    git

    git add .
    git commit -m 'laravel 資料庫 Seeder 練習完成
    
    database/seeds/UsersTableSeeder.php'
  2. 做個 Seeder 小實驗 (bonus)

    git branch

    先用 git 開一個 branch , 等會兒做完實驗, 可以返回剛剛的狀態

    命令

    git branch
    git branch -a
    git branch seeder2
    git branch
    git checkout seeder2

    執行結果

    [alex@nvda ~/jobs/testAuth ]$ git branch
          1 * master
    [alex@nvda ~/jobs/testAuth ]$ git branch -a
          1 * master
    [alex@nvda ~/jobs/testAuth ]$ git branch seeder2
    [alex@nvda ~/jobs/testAuth ]$ git branch
          1 * master
          2   seeder2
    [alex@nvda ~/jobs/testAuth ]$ git checkout seeder2
    Switched to branch 'seeder2'
    [alex@nvda ~/jobs/testAuth ]$ git branch
          1   master
          2 * seeder2
    [alex@nvda ~/jobs/testAuth ]$
    [alex@nvda ~/jobs/testAuth ]$

    實驗來源參考

    產生 Model 及 Migration

    我們需要 Film(影片), Genre(類型), Comment(評論) 這三個 Model 來做實驗, 執行下列命令後, 產生了 6 個 php 檔案

    命令

    php artisan make:model Film -m
    php artisan make:model Comment -m
    php artisan make:model Genre -m
    git st -s

    執行結果

    [alex@nvda ~/jobs/testAuth ]$ php artisan make:model Film -m
    Model created successfully.
    Created Migration: 2019_03_20_221753_create_films_table
    [alex@nvda ~/jobs/testAuth ]$ php artisan make:model Comment -m
    Model created successfully.
    Created Migration: 2019_03_20_221825_create_comments_table
    [alex@nvda ~/jobs/testAuth ]$ php artisan make:model Genre -m
    Model created successfully.
    Created Migration: 2019_03_20_221830_create_genres_table
    [alex@nvda ~/jobs/testAuth ]$
    [alex@nvda ~/jobs/testAuth ]$ git st -s
    ?? app/Comment.php
    ?? app/Film.php
    ?? app/Genre.php
    ?? database/migrations/2019_03_20_221753_create_films_table.php
    ?? database/migrations/2019_03_20_221825_create_comments_table.php
    ?? database/migrations/2019_03_20_221830_create_genres_table.php
    [alex@nvda ~/jobs/testAuth ]$

    Model 的欄位

    以下的檔案都在 /database/migrations/ 目錄下, 而且隨著每個人的建立時間產生不同的檔名, 檔名前段 年_月_日_時分秒_, 會用 ___ 省略顯示

    增修上面產生 3 個 Model 的欄位, 都在 public function up() 裡, 請看程式碼

    命令

    vi database/migrations/___create_genres_table.php
    vi database/migrations/___create_films_table.php
    vi database/migrations/___create_comments_table.php

    database/migrations/___create_genres_table.php 程式碼

    public function up()
    {
        Schema::create('genres', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->string('name');
            $table->timestamps();
        });
    }

    database/migrations/___create_films_table.php 程式碼

    public function up()
    {
        Schema::create('films', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->integer('user_id');
            $table->string('title');
            $table->text('description');
            $table->date('release_date');
            $table->enum('rating',[ 1, 2, 3, 4, 5] );
            $table->integer('genre_id');
            $table->string('photo');
            $table->string('slug');
            $table->timestamps();
        });
    }

    database/migrations/___create_comments_table.php 程式碼

    public function up()
    {
        Schema::create('comments', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->integer('user_id');
            $table->integer('film_id');
            $table->text('comment');
            $table->timestamps();
        });
    }

    git

    git add .

    產生 Factory 工廠程式碼

    命令

    php artisan make:factory GenreFactory --model=Genre
    php artisan make:factory FilmFactory --model=Film
    php artisan make:factory CommentFactory --model=Comment

    執行結果

    [alex@nvda ~/jobs/testAuth ]$ php artisan make:factory GenreFactory --model=Genre
    Factory created successfully.
    [alex@nvda ~/jobs/testAuth ]$ php artisan make:factory FilmFactory --model=Film
    Factory created successfully.
    [alex@nvda ~/jobs/testAuth ]$ php artisan make:factory CommentFactory --model=Comment
    Factory created successfully.
    [alex@nvda ~/jobs/testAuth ]$ git st -s
    ...(前略)
    ?? database/factories/CommentFactory.php
    ?? database/factories/FilmFactory.php
    ?? database/factories/GenreFactory.php
    [alex@nvda ~/jobs/testAuth ]$

    此時 3 個 Factory php 檔案裡 $factory->define() 函數是空的, 尚未有任何對應欄位的自動化回傳值. 我們來加一些程式碼, 才能讓工廠運作.

    命令

    vi database/factories/GenreFactory.php
    vi database/factories/FilmFactory.php
    vi database/factories/CommentFactory.php

    database/factories/GenreFactory.php 程式碼

    $factory->define(App\Genre::class, function (Faker $faker) {
        return [
            'name' => $faker->word, // 一個英文字
        ];
    });

    database/factories/FilmFactory.php 程式碼

    $factory->define(App\Film::class, function (Faker $faker) {
        return [
            'title' => $faker->sentence(5), // 5 個字以上的句子
            'description' => $faker->realText(rand(80, 600)), // 文章 80 ~ 600 字
            'release_date'  => $faker->date(),
            'rating' => rand(1,5),
            'genre_id' => function () {
                // Get random genre id
                return App\Genre::inRandomOrder()->first()->id;
            },
            'photo'  => 'https://via.placeholder.com/350x150',
            'slug'   => str_replace('--', '-', strtolower(preg_replace('/[^a-zA-Z0-9]/', '-', trim($faker->sentence(5))))),
        ];
    });

    database/factories/CommentFactory.php 程式碼

    $factory->define(App\Comment::class, function (Faker $faker) {
        return [
            'comment' => $faker->realText(rand(10, 300)), // 文章 10 ~ 300 字
        ];
    });

    產生 Seeder 類別程式碼

    工廠蓋好了, 我們要開始教工廠的員工如何生產我們要的產品(假資料), 這個作業前要先有 Seeder 類別, 這些類別不一定要跟 Model 一一對應, 有可能一對多或多對一, 看實際狀況來實作, 只是這個實驗剛好也用了 3 個 Seeder 類別

    命令

    php artisan make:seeder GenreTableSeeder
    php artisan make:seeder UserFilmSeeder
    php artisan make:seeder CommentTableSeeder
    git st -s

    執行結果

    [alex@nvda ~/jobs/testAuth ]$ php artisan make:seeder GenreTableSeeder
    Seeder created successfully.
    [alex@nvda ~/jobs/testAuth ]$ php artisan make:seeder UserFilmSeeder
    Seeder created successfully.
    [alex@nvda ~/jobs/testAuth ]$ php artisan make:seeder CommentTableSeeder
    Seeder created successfully.
    [alex@nvda ~/jobs/testAuth ]$
    [alex@nvda ~/jobs/testAuth ]$ git st -s
    ...(前略)
    ?? database/seeds/CommentTableSeeder.php
    ?? database/seeds/GenreTableSeeder.php
    ?? database/seeds/UserFilmSeeder.php
    [alex@nvda ~/jobs/testAuth ]$

    完成之後 database/seeds/ 目錄下會有 3 個新的 php 檔, 這一次同時我們要加入一些命令列對話及輸入, 來確定是否真的要執行, 以及執行生產的數量(筆數). 這樣更方便我們隨時可以調整測試, 現在修改剛剛產生出來的工廠生產程式碼. 有點長, 花點時間慢慢消化, 說明就在程式裡.

    database/seeds/GenreTableSeeder.php 程式碼

    public function run()
    {
        // 要生產多少種 genres (類型) ? 預設值是 10 種 genre (10 筆資料列)
        $count = (int)$this->command->ask('請問要生產多少種類型 (genres) ?', 10);
    
        $this->command->info('工廠生產將會建立 {$count} 筆 genres (類型).');
    
        // 工廠開工生產 $count 筆資料
        $genres = factory(App\Genre::class, $count)->create();
    
        $this->command->info('Genres(類型) 生產建立完成!');
    }

    database/seeds/UserFilmSeeder.php 程式碼

    public function run()
    {
        // 要生產多少個 users (用戶) ? 預設值是 8 個 user (10 筆資料列)
        $userCount = (int)$this->command->ask('請問要生產多少個 users (會員) ?', 8);
    
        // 詢問每位 user 要生產 film (影片) 的範圍, 預設值是 0 ~ 10 筆
        $r = 0 . '-' . 10;
        $filmRange = $this->command->ask('請問每位 user 要生產多少支 films (影片) ? 務必要輸入 - 在兩個數字之間, 例如 3-8, 否則會發生錯誤', $r);
    
        $this->command->info('工廠生產將會建立 {$userCount} 個 users , 每位 user (會員) 會生產 films (影片) 的範圍為 {$filmRange}.');
    
        // 工廠開工生產 $userCount 筆 user 資料
        $users = factory(App\User::class, $userCount)->create();
    
        // 工廠對每位 user 生產 '亂數' 筆 (在下方 count($range) 函數, 亂數產生) films (影片)
        $users->each(function($user) use ($filmRange){
            factory(App\Film::class, $this->count($filmRange))
                    ->create(['user_id' => $user->id]);
        });
    
        $this->command->info('Users(會員)及Films(影片) 生產建立完成!');
    }
    
    // Return random value in given range
    function count($range)
    {
        return rand(...explode('-', $range));
    }

    database/seeds/CommentTableSeeder.php 程式碼

    public function run()
    {
        $r = 5 . '-' . 9;
        $commentRange = $this->command->ask('請問每支 film (影片) 要生產多少個 comments (評論) ? 務必要輸入 - 在兩個數字之間, 例如 3-8, 否則會發生錯誤', $r);
    
        $films = App\Film::all();
    
        $this->command->info('工廠生產將會建立 {$commentRange} 不等的 comments (評論)數, 給 {$films->count()} 支 films (影片).');
    
        // 工廠開工對有限圍的每一 films (影片) 生產 $commentRange (筆數不定) comments 資料
        $films->each(function($film) use ($commentRange){
            factory(App\Comment::class, $this->count($commentRange))
                ->create([
                       'film_id' => $film->id,
                       'user_id' => App\User::all()->random()->id
                    ]);
        });
        $this->command->info('Comments(評論) 生產建立完成!');
    }
    
    // Return random value in given range
    function count($range)
    {
        return rand(...explode('-', $range));
    }

    Seeder 總管

    這支程式總管所有 Seeder , 一樣也是修改 public function run() 函數成下面的程式碼, 注意, 原本 $this->call(UsersTableSeeder::class); 是先前生產時用的, 現在暫時先用 // 把它註解不執行, 我們同時也加上確認問句 "是否要清空所有資料表並重新建立" ?

    database/seeds/DatabaseSeeder.php 程式碼

    public function run()
    {
        // $this->call(UsersTableSeeder::class); // 暫時先不執行
    
        Eloquent::unguard();
    
        // 詢問是否要 Ask for db migration refresh, default is no
        if ($this->command->confirm('請問在資料填充前, 是否要清空所有資料表並重新建立, 原資料庫會全數刪除 ? Do you wish to refresh migration before seeding, it will clear all old data ?')) {
    
            // 直接呼叫 php artisan migrate:fresh
            $this->command->call('migrate:fresh');
    
            $this->command->line('資料庫資料表清除完成. Database cleared.');
        }
    
        $this->call([
            GenreTableSeeder::class ,
            UserFilmSeeder::class ,
            CommentTableSeeder::class ,
        ]);
    
        $this->command->info('資料庫資料填充完成. Database seeded.');
    
        // Re Guard model
        Eloquent::reguard();
    }

    萬事俱備, 只欠東風......

    資料庫產生 3 個 Model 資料表

    上面程式碼的工作都寫好存檔後, 先做一次 migrate 把新增的 3 個 Film(影片), Comment(評論), Genre(類型) 資料表產生到資料庫

    命令

    [alex@nvda ~/jobs/testAuth ]$ php artisan migrate:status
    +------+------------------------------------------------+-------+
    | Ran? | Migration                                      | Batch |
    +------+------------------------------------------------+-------+
    | Yes  | 2014_10_12_000000_create_users_table           | 1     |
    | Yes  | 2014_10_12_100000_create_password_resets_table | 1     |
    | No   | 2019_03_20_221753_create_films_table           |       |
    | No   | 2019_03_20_221825_create_comments_table        |       |
    | No   | 2019_03_20_221830_create_genres_table          |       |
    +------+------------------------------------------------+-------+
    [alex@nvda ~/jobs/testAuth ]$ php artisan migrate
    Migrating: 2019_03_20_221753_create_films_table
    Migrated:  2019_03_20_221753_create_films_table
    Migrating: 2019_03_20_221825_create_comments_table
    Migrated:  2019_03_20_221825_create_comments_table
    Migrating: 2019_03_20_221830_create_genres_table
    Migrated:  2019_03_20_221830_create_genres_table
    [alex@nvda ~/jobs/testAuth ]$ php artisan migrate:status
    +------+------------------------------------------------+-------+
    | Ran? | Migration                                      | Batch |
    +------+------------------------------------------------+-------+
    | Yes  | 2014_10_12_000000_create_users_table           | 1     |
    | Yes  | 2014_10_12_100000_create_password_resets_table | 1     |
    | Yes  | 2019_03_20_221753_create_films_table           | 2     |
    | Yes  | 2019_03_20_221825_create_comments_table        | 2     |
    | Yes  | 2019_03_20_221830_create_genres_table          | 2     |
    +------+------------------------------------------------+-------+
    [alex@nvda ~/jobs/testAuth ]$

    進入 mysql 用 show tables 查看

    執行結果

    mysql> show tables;
    +-----------------------+
    | Tables_in_d1_lta1     |
    +-----------------------+
    | comments              |
    | films                 |
    | genres                |
    | migrations            |
    | users                 |
    +-----------------------+
    5 rows in set (0.00 sec)

    生產一條龍

    命令

    php artisan db:seed

    先一直按 ENTER 用 Seeder 程式內的預設值, 可能會順利一點, 第二次再試試調整不同的設定值, 打錯了, 可能會發生錯誤, 再去比對 Seeder 程式碼做修正.

    執行結果

    [alex@nvda ~/jobs/testAuth ]$ php artisan db:seed
    
     請問在資料填充前, 是否要清空所有資料表並重新建立, 原資料庫會全數刪除 ? Do you wish to refresh migration before seeding, it will clear all old data ? (yes/no) [no]:
     >
    
    Seeding: GenreTableSeeder
    
     請問要生產多少種類型 (genres) ? [10]:
     >
    
    工廠生產將會建立 {$count} 筆 genres (類型).
    Genres(類型) 生產建立完成!
    Seeding: UserFilmSeeder
    
     請問要生產多少個 users (會員) ? [8]:
     >
    
     請問每位 user 要生產多少支 films (影片) ? 務必要輸入 - 在兩個數字之間, 例如 3-8, 否則會發生錯誤 [0-10]:
     >
    
    工廠生產將會建立 {$userCount} 個 users , 每位 user (會員) 會生產 films (影片) 的範圍為 {$filmRange}.
    Users(會員)及Films(影片) 生產建立完成!
    Seeding: CommentTableSeeder
    
     請問每支 film (影片) 要生產多少個 comments (評論) ? 務必要輸入 - 在兩個數字之間, 例如 3-8, 否則會發生錯誤 [5-9]:
     >
    
    工廠生產將會建立 {$commentRange} 不等的 comments (評論)數, 給 {$films->count()} 支 films (影片).
    
    Comments(評論) 生產建立完成!
    資料庫資料填充完成. Database seeded.
    Database seeding completed successfully.
    [alex@nvda ~/jobs/testAuth ]$
    [alex@nvda ~/jobs/testAuth ]$

    進入 mysql 查看工廠大量生產 films, genres, comments 假資料的狀況 Film(影片), Genre(類型), Comment(評論)

    查看資料表

    注意 MYDATABASE 要改成自己使用的 database 名稱

    命令

    SELECT table_name, table_rows FROM information_schema.tables
    WHERE table_schema in ('MYDATABASE') AND table_name in ('films', 'genres', 'comments') LIMIT 9;

    執行結果

    mysql> SELECT table_name, table_rows FROM information_schema.tables
    WHERE table_schema in ('MYDATABASE') AND table_name in ('films', 'genres', 'comments', 'users') LIMIT 9;
    +------------+------------+
    | table_name | table_rows |
    +------------+------------+
    | comments   |        251 |
    | films      |         36 |
    | genres     |         10 |
    +------------+------------+
    3 rows in set (0.00 sec)

    用 migrate:rollback 重來一次 db:seed

    正常來說, 如果不要使用 migrate:fresh 重設所有資料表, 它會一直累加填充 (INSERT) 資料進去資料表

    現在我們練習 migrate:rollback, 這個命令, 會 DROP 最後一次 CREATE 的 TABLE, 就是 films, genres, comments 這三個資料表, 所以它不會影響到上一次或更早以前已經 CREATE 的 TABLE

    命令

    [alex@nvda ~/jobs/testAuth ]$ php artisan migrate:rollback
    Rolling back: 2019_03_20_221830_create_genres_table
    Rolled back:  2019_03_20_221830_create_genres_table
    Rolling back: 2019_03_20_221825_create_comments_table
    Rolled back:  2019_03_20_221825_create_comments_table
    Rolling back: 2019_03_20_221753_create_films_table
    Rolled back:  2019_03_20_221753_create_films_table
    [alex@nvda ~/jobs/testAuth ]$ php artisan migrate:status
    +------+------------------------------------------------+-------+
    | Ran? | Migration                                      | Batch |
    +------+------------------------------------------------+-------+
    | Yes  | 2014_10_12_000000_create_users_table           | 1     |
    | Yes  | 2014_10_12_100000_create_password_resets_table | 1     |
    | Yes  | 2019_03_18_110234_create_permission_tables     | 1     |
    | No   | 2019_03_20_221753_create_films_table           |       |
    | No   | 2019_03_20_221825_create_comments_table        |       |
    | No   | 2019_03_20_221830_create_genres_table          |       |
    +------+------------------------------------------------+-------+
    [alex@nvda ~/jobs/testAuth ]$

    進入 mysql 用 show tables 查看

    執行結果

    mysql> show tables;
    +-----------------------+
    | Tables_in_d1_lta1     |
    +-----------------------+
    | migrations            |
    | users                 |
    +-----------------------+
    2 rows in set (0.00 sec)

    這個時候 3 個資料表都會消失, 所以我們再用 php artisan migrate 重建

    執行結果

    [alex@nvda ~/jobs/testAuth ]$ php artisan migrate
    Migrating: 2019_03_20_221753_create_films_table
    Migrated:  2019_03_20_221753_create_films_table
    Migrating: 2019_03_20_221825_create_comments_table
    Migrated:  2019_03_20_221825_create_comments_table
    Migrating: 2019_03_20_221830_create_genres_table
    Migrated:  2019_03_20_221830_create_genres_table
    [alex@nvda ~/jobs/testAuth ]$ php artisan migrate:status
    +------+------------------------------------------------+-------+
    | Ran? | Migration                                      | Batch |
    +------+------------------------------------------------+-------+
    | Yes  | 2014_10_12_000000_create_users_table           | 1     |
    | Yes  | 2014_10_12_100000_create_password_resets_table | 1     |
    | Yes  | 2019_03_18_110234_create_permission_tables     | 1     |
    | Yes  | 2019_03_20_221753_create_films_table           | 2     |
    | Yes  | 2019_03_20_221825_create_comments_table        | 2     |
    | Yes  | 2019_03_20_221830_create_genres_table          | 2     |
    +------+------------------------------------------------+-------+
    [alex@nvda ~/jobs/testAuth ]$

    此刻, 這三個資料表都是空的

    GOTO 生產一條龍 多試幾次 :-D

    還有一件事...本地中文化

    剛剛作出來的假資料, 內容都是英文, 但是, 也可以生產中文假資料, 我們只要修改 config/app.php 裡的 'faker_locale' 值為 'zh_TW' 即可, 預設為 'en_US'

    命令

    vi config/app.php

    執行結果

    'faker_locale' => 'zh_TW', // 'en_US',

    存檔, 再 GOTO 生產一條龍, 查看資料庫, 嘿嘿......有中文, 有中文, 有中文, 雖然不完美

    git

    git add .
    git commit -m '在 branch seed2 做 seeder 小實驗'
    git log -3
    git checkout master

    執行結果

    [alex@nvda ~/jobs/testAuth ]$ git log -3
          1 commit 970bc558d0fad5afdc7465b84ce07640bf88338c (HEAD -> seeder2)
          2 Author: ak4 <ak4567@gmail.com>
          3 Date:   Thu Mar 21 20:34:04 2019 +0800
          4
          5     在 branch seed2 做 seeder 小實驗
          6
          7 commit c693f76397b85400e6effd441848a8888b5c8cc4 (master)
          8 Author: ak4 <ak4567@gmail.com>
          9 Date:   Wed Mar 20 20:04:07 2019 +0800
         10
         11     laravel 資料庫 Seeder 練習
         12
         13     database/seeds/UsersTableSeeder.php
         14
         15 commit 57c8cdbdf9cec7169a690ac99132564284b9e6c4
         16 Author: ak4 <ak4567@gmail.com>
         17 Date:   Wed Mar 20 12:38:39 2019 +0800
         18
         19     Daily Commit @190319
    [alex@nvda ~/jobs/testAuth ]$
    
    [alex@nvda ~/jobs/testAuth ]$ git checkout master
    Switched to branch 'master'
    [alex@nvda ~/jobs/testAuth ]$ git log -3
          1 commit c693f76397b85400e6effd441848a8888b5c8cc4 (HEAD -> master)
          2 Author: ak4 <ak4567@gmail.com>
          3 Date:   Wed Mar 20 20:04:07 2019 +0800
          4
          5     laravel 資料庫 Seeder 練習
          6
          7     database/seeds/UsersTableSeeder.php
          8
          9 commit 57c8cdbdf9cec7169a690ac99132564284b9e6c4
         10 Author: ak4 <ak4567@gmail.com>
         11 Date:   Wed Mar 20 12:38:39 2019 +0800
         12
         13     Daily Commit @190319
         14
         15 commit 1a0f3510cd85f1ca491d1bdbe79712bcd40f9ea3
         16 Author: ak4 <ak4567@gmail.com>
         17 Date:   Tue Mar 19 09:04:13 2019 +0800
         18
         19     spatie/laravel-permission 安裝
         20
         21     尚未測試
    [alex@nvda ~/jobs/testAuth ]$

    注意最後兩個 log commit 裡的 (...), 跟 branch 的 master seeder2 有關, 當我們執行完最後 git checkout master, 再回去檢查檔案內容, 這個 seeder 小實驗 (bonus) 在 database/ 目錄下產生的 9 個檔案, 都完全消失了. 甚至 config/app.php 裡面, 為了中文本地化而設定的'faker_locale' => 'zh_TW' 都變回原來的 'en_US'

    哈哈, 別擔心, 神奇的傑克又回來了, 我們再下一個 git checkout seeder2

    git

    git checkout seeder2
    git log -3

    執行結果

    [alex@nvda ~/jobs/testAuth ]$ git checkout seeder2
    Switched to branch 'seeder2'
    [alex@nvda ~/jobs/testAuth ]$ git log -3
          1 commit 970bc558d0fad5afdc7465b84ce07640bf88338c (HEAD -> seeder2)
          2 Author: ak4 <ak4567@gmail.com>
          3 Date:   Thu Mar 21 20:34:04 2019 +0800
          4
          5     在 branch seed2 做 seeder 小實驗
          6
          7 commit c693f76397b85400e6effd441848a8888b5c8cc4 (master)
          8 Author: ak4 <ak4567@gmail.com>
          9 Date:   Wed Mar 20 20:04:07 2019 +0800
         10
         11     laravel 資料庫 Seeder 練習
         12
         13     database/seeds/UsersTableSeeder.php
         14
         15 commit 57c8cdbdf9cec7169a690ac99132564284b9e6c4
         16 Author: ak4 <ak4567@gmail.com>
         17 Date:   Wed Mar 20 12:38:39 2019 +0800
         18
         19     Daily Commit @190319
    [alex@nvda ~/jobs/testAuth ]$

    再檢查看看那些消失在亞特蘭提斯的檔案, 是否又回到地球了, 以上的動作, 等待 git 再詳細解說, 先玩玩看

  3. 本章總結

    本章使用 laravel , git 命令總結

    php artisan make:seeder UsersTableSeeder        # 建立 Seeder Class
    composer dump-autoload                          # 重建 autoload 自動載入程式
    php artisan make:model Film -m                  # 產生單一 Model
    php artisan make:factory FilmFactory --model=Film   # 產生單一 factory
    php artisan make:seeder GenreTableSeeder        # 產生單一 seeder
    php artisan migrate                             # 生成及遷移尚未處理的資料庫
    php artisan migrate:rollback                    # 回滾最後一次遷移的資料庫
    php artisan migrate:status                      # 資料庫最後遷移的狀態
    php artisan db:seed                             # 產生全部 Seeder 的 seed 資料
    php artisan db:seed --class=UsersTableSeeder    # 產生單一 Seeder 的 seed 資料
    git branch                                      # 查看 git 分支及現在位置
    git branch -a                                   # 查看 git 分支及現在位置
    git branch seeder2                              # 建立新的 git 分支, 並切換到此分支位置
    git log -3                                      # 查看 git 現在位置的最後 3 筆 commit
    git checkout seeder2                            # 切換到 seeder 分支
    git checkout master                             # 切換到 master(主幹線) 分支