Laravel 마이그레이션 파일에 데이터베이스 채우기


115

저는 방금 Laravel을 배우고 있으며 사용자 테이블을 만드는 작업 마이그레이션 파일이 있습니다. 마이그레이션의 일부로 사용자 레코드를 채우려 고합니다.

public function up()
{
    Schema::create('users', function($table){

        $table->increments('id');
        $table->string('email', 255);
        $table->string('password', 64);
        $table->boolean('verified');
        $table->string('token', 255);
        $table->timestamps();

        DB::table('users')->insert(
            array(
                'email' => 'name@domain.com',
                'verified' => true
            )
        );

    });
}

하지만 실행할 때 다음 오류가 발생합니다 php artisan migrate.

SQLSTATE[42S02]: Base table or view not found: 1146 Table 'vantage.users' doesn't exist

이는 Artisan이 아직 테이블을 생성하지 않았기 때문이지만 모든 문서에는 Fluent Query를 사용하여 마이그레이션의 일부로 데이터를 채우는 방법이 있다고 말하는 것 같습니다.

누구든지 어떻게 알아? 감사!

답변:


215

DB :: insert ()를 Schema :: create () 안에 넣지 마십시오. create 메서드가 테이블 만들기를 완료해야 항목을 삽입 할 수 있기 때문입니다. 대신 이것을 시도하십시오.

public function up()
{
    // Create the table
    Schema::create('users', function($table){
        $table->increments('id');
        $table->string('email', 255);
        $table->string('password', 64);
        $table->boolean('verified');
        $table->string('token', 255);
        $table->timestamps();
    });

    // Insert some stuff
    DB::table('users')->insert(
        array(
            'email' => 'name@domain.com',
            'verified' => true
        )
    );
}

5
여러 데이터를 삽입하는 방법은 무엇입니까?
Sahbaz

6
SuperMario'sYoshi @ 나는이 같은 생각DB::table('users')->insert([ ['email' => 'taylor@example.com', 'votes' => 0], ['email' => 'dayle@example.com', 'votes' => 0] ]);
Денис

80

나는 이것이 오래된 게시물이라는 것을 알고 있지만 Google 검색에 나오기 때문에 여기에서 지식을 공유 할 것이라고 생각했습니다. @ erin-geyer는 마이그레이션과 시더를 혼합하면 골칫거리가 될 수 있다고 지적했으며 @justamartin은 때때로 배포의 일부로 데이터를 채우고 싶거나 필요하다고 반박했습니다.

한 단계 더 나아가서 예를 들어 스테이징에 배포하고 모든 것이 정상인지 확인한 다음 동일한 결과에 대한 확신을 가지고 프로덕션에 배포 할 수 있도록 데이터 변경 사항을 지속적으로 롤아웃 할 수있는 것이 바람직하다고 말할 수 있습니다. (수동 단계를 실행하는 것을 기억할 필요가 없습니다).

그러나 시드와 마이그레이션은 서로 관련이 있지만 별개의 문제이므로 분리하는 데 여전히 가치가 있습니다. 우리 팀은 시더라고 부르는 마이그레이션을 만들어 타협했습니다. 이것은 다음과 같습니다.

public function up()
{
    Artisan::call( 'db:seed', [
        '--class' => 'SomeSeeder',
        '--force' => true ]
    );
}

이를 통해 마이그레이션과 마찬가지로 시드를 한 번 실행할 수 있습니다. 동작을 방지하거나 강화하는 논리를 구현할 수도 있습니다. 예를 들면 :

public function up()
{
    if ( SomeModel::count() < 10 )
    {
        Artisan::call( 'db:seed', [
            '--class' => 'SomeSeeder',
            '--force' => true ]
        );
    }
}

SomeModels가 10 개 미만인 경우 조건부로 시더를 실행합니다. 이것은 호출 artisan db:seed할 때뿐만 아니라 마이그레이션 할 때 실행되는 표준 시더로 시더를 포함하여 "이중"하지 않도록하는 경우에 유용합니다. 롤백이 예상대로 작동하도록 역 시더를 만들 수도 있습니다.

public function down()
{
    Artisan::call( 'db:seed', [
        '--class' => 'ReverseSomeSeeder',
        '--force' => true ]
    );
}

두 번째 매개 변수 --force는 시더가 프로덕션 환경에서 실행되도록하는 데 필요합니다.


2
이것이 가장 좋은 대답입니다. 관심사를 분리하는 유지 가능한 코드!
helsont

18
마이그레이션 스크립트에서 시더를 호출하는 장기적 의미를 신중하게 고려할 것입니다. 마이그레이션 스크립트는 날짜 / 시간 버전이 지정되지만 시더는 일반적으로 그렇지 않습니다. 개발 중 시더는 자주 변경되어야하므로 버전이없는 시더를 실행하는 버전이 지정된 마이그레이션 스크립트가 멱 등성을 깨뜨릴 가능성이 있습니다. 즉, 매일 동일한 마이그레이션 스크립트 세트를 실행하면 다른 결과가 나올 수 있습니다.
originalbryan

2
이 글을 게시 한 지 오래되었고이 기법을 사용한 경험을 제공하고 싶었습니다. 전반적으로 그것은 우리에게 잘 작동했으며 다시해야한다면 나는 할 것입니다. 그것은 알아야 할 것이 하나 있다고 말했습니다. @originalbryan이 정확히 맞고 그 결과 마이그레이션이 실행될 때 시더 (및 모델)가 데이터베이스보다 더 최신 상태이기 때문에 새 DB를 가동 할 때 마이그레이션이 중단되는 상황이 발생하는 경우가 있습니다 (시드 할 수 있기 때문에 스키마가 완전히 업데이트되기 전에). 이 경우 문제를 해결하기 위해 이전 마이그레이션을 업데이트합니다.
darrylkuhn

나는 그것이 오래된 마이그레이션 파일을 업데이트하는 것은 좋은 방법이 아닙니다 듣고 @darrylkuhn - 대신 오래된 파일을 업데이트하는, 당신은 새로운 마이그레이션 파일을 작성해야합니다 - 이것이 디자인으로 마이그레이션 파일에 대해 "흐름"
카밀 Kiełczewski

2
라 라벨의 모든 언어는 시더가 테스트 데이터를위한 것임을 의미하므로 디자인시 염두에 두어야한다고 생각합니다. 앱의 일부인 데이터와 테스트 데이터를 구분하는 것이 중요하며 마이그레이션에 필요한 데이터를 직접 포함하면 이러한 구분이 매우 명확 해집니다.
Brettins

13

다음은 마이그레이션을 사용하는 것보다 Laravel의 Database Seeder를 사용하는 것이 더 나은 이유에 대한 아주 좋은 설명입니다 : http://laravelbook.com/laravel-database-seeding/

위의 링크에 설명 된 구현이 작동하지 않고 불완전하기 때문에 공식 문서의 지침을 따르는 것이 훨씬 더 좋은 생각입니다. http://laravel.com/docs/migrations#database-seeding


1
에린의 말에 동의합니다. 개발 환경에서 일부 데이터를 시드하고 싶지만 프로덕션 환경에서는 시드하지 않을 가능성이 높으므로 마이그레이션을 시드 데이터와 혼합하지 마십시오.
Daniel Vigueras 2014-09-08

18
좋은 지적이지만 프로덕션 환경에 일부 데이터가 있어야하는 상황이 있습니다. 예를 들어, 고객이 처음으로 로그인 할 수 있도록 첫 번째 기본 관리자가 존재해야하고 사전 설정된 권한 부여 역할이 존재해야하며 일부 비즈니스 로직 데이터가 즉시 필요할 수도 있습니다. 따라서 마이그레이션에 필수 데이터를 추가해야한다고 생각하지만 (별도의 마이그레이션을 통해 데이터 레코드도 업 / 다운 할 수 있도록) 개발을 위해 시드가 남을 수 있습니다.
JustAMartin 2015

작은 메모; 데이터베이스 시딩에 대한 링크는 지금 : laravel.com/docs/5.3/seeding
magikMaker

3

이것은 당신이 원하는 것을해야합니다.

public function up()
{
    DB::table('user')->insert(array('username'=>'dude', 'password'=>'z19pers!'));
}

1

이를 수행하는 또 다른 깨끗한 방법은 인스턴스를 만들고 관련 모델을 유지하는 개인 메서드를 정의하는 것입니다.

public function up()
{
    Schema::create('roles', function (Blueprint $table) {
        $table->increments('id');
        $table->string('label', 256);
        $table->timestamps();
        $table->softDeletes();
    });

    $this->postCreate('admin', 'user');
}

private function postCreate(string ...$roles)  {
    foreach ($roles as $role) {
        $model = new Role();
        $model->setAttribute('label', $role);
        $model->save();
    }
}

이 솔루션을 사용하면 타임 스탬프 필드가 Eloquent에 의해 생성됩니다.

편집 : 데이터베이스 구조 생성 및 데이터베이스 채우기를 구별하기 위해 시더 시스템을 사용하는 것이 좋습니다.


나는 이것을 좋아한다. 그것은 내가해야 할 일을 정확히 서버에두고 마이그레이션에 기본적으로 몇 가지 사용자 역할을 추가한다. 모델을 가져 오거나 직접 참조해야 $model = new App\UserRoles();하지만 그 외에는 완벽합니다!
FAB

1

이 DB 삽입 방법을 시도했지만 모델을 사용하지 않기 때문에 모델에 대한 느린 특성을 무시했습니다. 따라서이 테이블에 대한 모델이 존재하는 경우 마이그레이션하자마자 모델을 사용하여 데이터를 삽입 할 수 있다고 생각했습니다. 그리고 나는 이것을 생각해 냈습니다.

public function up() {
        Schema::create('parent_categories', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->string('name');
            $table->string('slug');
            $table->timestamps();
        });
        ParentCategory::create(
            [
                'id' => 1,
                'name' => 'Occasions',
            ],
        );
    }

이것은 올바르게 작동했으며 내 모델의 느린 특성을 고려하여이 항목에 대한 슬러그를 자동으로 생성하고 타임 스탬프도 사용합니다. NB. ID를 추가 할 필요는 없었지만이 예에서는 카테고리에 대한 특정 ID를 원했습니다. Laravel 5.8에서 작업 테스트


0

이미 열을 채우고 새 열을 추가했거나 새 모의 값으로 이전 열을 채우려면 다음을 수행하십시오.

public function up()
{
    DB::table('foydabars')->update(
        array(
            'status' => '0'
        )
    );
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.