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.