시딩이란
시딩(Seeding)은 데이터베이스에 샘플 데이터나 초기 데이터를 투입하는 구조입니다.
개발 환경 설정이나 자동 테스트에서는 미리 데이터가 들어 있는 상태가 필요합니다. 매번 수동으로 데이터를 입력하는 것은 번거롭기 때문에 시더를 사용해 반복 실행 가능한 형태로 정리합니다.
시더 클래스는 database/seeders 디렉터리에 저장됩니다. 기본적으로 DatabaseSeeder 클래스가 준비되어 있습니다.
시더 생성
make:seeder Artisan 명령으로 새 시더 클래스를 생성합니다.
php artisan make:seeder UserSeeder
생성된 파일은 database/seeders/UserSeeder.php에 배치됩니다.
<? php
namespace Database\Seeders ;
use Illuminate\Database\ Seeder ;
class UserSeeder extends Seeder
{
/**
* 시더를 실행한다
*/
public function run () : void
{
// 여기에 데이터 투입 처리를 작성한다
}
}
시더 구현
run() 메서드 내부에 데이터 투입 처리를 작성합니다. DB 파사드나 Eloquent 모델을 사용해 삽입할 수 있습니다.
DB 파사드를 사용하는 방법
<? php
namespace Database\Seeders ;
use Illuminate\Database\ Seeder ;
use Illuminate\Support\Facades\ DB ;
use Illuminate\Support\Facades\ Hash ;
class UserSeeder extends Seeder
{
public function run () : void
{
DB :: table ( 'users' ) -> insert ([
[
'name' => '홍길동' ,
'email' => '[email protected] ' ,
'password' => Hash :: make ( 'password' ),
'created_at' => now (),
'updated_at' => now (),
],
[
'name' => '김하나' ,
'email' => '[email protected] ' ,
'password' => Hash :: make ( 'password' ),
'created_at' => now (),
'updated_at' => now (),
],
]);
}
}
Eloquent 모델을 사용하는 방법
use App\Models\ User ;
use Illuminate\Support\Facades\ Hash ;
public function run () : void
{
User :: create ([
'name' => '관리자' ,
'email' => '[email protected] ' ,
'password' => Hash :: make ( 'password' ),
]);
}
시딩 실행 중에는 매스 어사인먼트 보호가 자동으로 무효화됩니다. $fillable이나 $guarded 설정에 신경 쓰지 않고 데이터를 삽입할 수 있습니다.
모델 팩토리와의 조합
대량의 테스트 데이터가 필요한 경우에는 모델 팩토리 와의 조합이 편리합니다. 팩토리를 사용하면 랜덤한 더미 데이터를 일괄 생성할 수 있습니다.
use App\Models\ User ;
use App\Models\ Post ;
public function run () : void
{
// 10명의 사용자를 생성
User :: factory ( 10 ) -> create ();
// 각 사용자에게 3건의 게시물을 생성
User :: factory ( 5 )
-> hasPosts ( 3 )
-> create ();
}
팩토리의 자세한 사용법은 Eloquent 팩토리 문서를 참조해 주세요.
DatabaseSeeder 사용법
DatabaseSeeder는 여러 시더를 통합 관리하는 진입점입니다. call() 메서드로 실행할 시더를 지정합니다.
<? php
namespace Database\Seeders ;
use Illuminate\Database\ Seeder ;
class DatabaseSeeder extends Seeder
{
public function run () : void
{
$this -> call ([
UserSeeder :: class ,
PostSeeder :: class ,
CommentSeeder :: class ,
]);
}
}
call()에 전달한 순서로 시더가 실행됩니다. 외래 키 제약이 있는 경우에는 참조 대상 테이블을 먼저 시드하는 순서로 해 주세요(예: users → posts).
시더 실행
전체 시더 실행
DatabaseSeeder가 호출되고, 거기서 call()로 지정한 시더가 순서대로 실행됩니다.
특정 시더만 실행
--class 옵션으로 실행할 시더 클래스를 지정할 수 있습니다.
php artisan db:seed --class=UserSeeder
마이그레이션과 동시에 실행
migrate:fresh 명령에 --seed 옵션을 붙이면, 전체 테이블을 재생성한 후 시딩을 일괄 실행할 수 있습니다.
php artisan migrate:fresh --seed
특정 시더만 실행하고 싶은 경우에는 --seeder 옵션을 사용합니다.
php artisan migrate:fresh --seed --seeder=UserSeeder
migrate:fresh는 모든 테이블을 삭제하고 다시 만듭니다. 기존 데이터가 모두 사라지므로 프로덕션 환경에서는 사용하지 마세요.
프로덕션 환경에서 실행
프로덕션 환경에서 시딩을 실행하려고 하면 확인 프롬프트가 표시됩니다. 확인 없이 실행하려면 --force 플래그를 사용합니다.
php artisan db:seed --force
프로덕션 환경에서의 시딩은 데이터의 덮어쓰기나 손실로 이어질 수 있습니다. 실행 전에 반드시 백업을 받아 주세요.
모델 이벤트 억제
시딩 중에 모델의 이벤트(creating, created 등)가 발생하는 것을 방지하고 싶은 경우에는 WithoutModelEvents 트레이트를 사용합니다.
<? php
namespace Database\Seeders ;
use Illuminate\Database\ Seeder ;
use Illuminate\Database\Console\Seeds\ WithoutModelEvents ;
class DatabaseSeeder extends Seeder
{
use WithoutModelEvents ;
public function run () : void
{
$this -> call ([
UserSeeder :: class ,
]);
}
}
call()을 통해 실행되는 자식 시더에도 적용됩니다.
실전 예시: 블로그 앱의 시더
사용자와 게시물을 가진 블로그 앱의 초기 데이터를 세팅하는 예시입니다.
// database/seeders/UserSeeder.php
class UserSeeder extends Seeder
{
public function run () : void
{
User :: factory ( 10 ) -> create ();
}
}
// database/seeders/PostSeeder.php
class PostSeeder extends Seeder
{
public function run () : void
{
// 각 사용자에게 2~5건의 게시물을 생성
User :: all () -> each ( function ( $user ) {
Post :: factory ( rand ( 2 , 5 )) -> create ([
'user_id' => $user -> id ,
]);
});
}
}
// database/seeders/DatabaseSeeder.php
class DatabaseSeeder extends Seeder
{
public function run () : void
{
$this -> call ([
UserSeeder :: class ,
PostSeeder :: class , // users 이후에 실행
]);
}
}
실행 순서:
php artisan migrate:fresh --seed
다음 단계
Eloquent 입문 시더로 투입한 데이터를 Eloquent ORM으로 가져오고 조작하는 방법을 배웁니다.