열을 Nullable로 만들기위한 Laravel 마이그레이션 변경


194

unsigned로 마이그레이션을 만들었습니다 user_id. user_id새 마이그레이션에서 편집 하여 어떻게 만들 수 nullable()있습니까?

Schema::create('throttle', function(Blueprint $table)
{
    $table->increments('id');
    // this needs to also be nullable, how should the next migration be?
    $table->integer('user_id')->unsigned();
}

답변:


265

Laravel 5는 이제 열 변경을 지원합니다. 다음은 공식 문서의 예입니다.

Schema::table('users', function($table)
{
    $table->string('name', 50)->nullable()->change();
});

출처 : http://laravel.com/docs/5.0/schema#changing-columns

Laravel 4는 열 수정을 지원하지 않으므로 원시 SQL 명령 작성과 같은 다른 기술을 사용해야합니다. 예를 들면 다음과 같습니다.

// getting Laravel App Instance
$app = app();

// getting laravel main version
$laravelVer = explode('.',$app::VERSION);

switch ($laravelVer[0]) {

    // Laravel 4
    case('4'):

        DB::statement('ALTER TABLE `pro_categories_langs` MODIFY `name` VARCHAR(100) NULL;');
        break;

    // Laravel 5, or Laravel 6
    default:                

        Schema::table('pro_categories_langs', function(Blueprint $t) {
            $t->string('name', 100)->nullable()->change();
        });               

}

3
이것에 대한 Thx. 그러나 어떻게 반대를 할 수 있습니까? 열이 Null을 허용하지 않도록 변경하는 방법은 무엇입니까? 어떤 아이디어?
algorhythm

@algorhythm이 '$ t-> string ('name ', 100)-> change ();'시도해보십시오
MURATSPLAT

7
마이그레이션하려면 교리 \ dbal이 필요합니다
younes0

33
@algorhythm ->nullable(false)를 사용하면 열을 다시 변경할 수 있습니다.
Colin

9
-> change ()를 사용하려면 Doctrine DBAL 패키지를 설치해야하며 laravel에서 즉시 사용할 수있는 동일한 열 유형을 모두 인식하지 못합니다. 예를 들어 double은 DBAL에서 인식되는 열 유형이 아닙니다.
Will Vincent

175

미래 독자를위한 완벽한 답변입니다. 이것은 Laravel 5 이상에서만 가능합니다.

우선 교리 / dbal 패키지 가 필요합니다 .

composer require doctrine/dbal

이제 마이그레이션에서 열을 nullable로 만들 수 있습니다.

public function up()
{
    Schema::table('users', function (Blueprint $table) {
        // change() tells the Schema builder that we are altering a table
        $table->integer('user_id')->unsigned()->nullable()->change();
    });
}

이 작업을 되 돌리는 방법이 궁금 할 것입니다. 슬프게도이 구문은 지원되지 않습니다.

// Sadly does not work :'(
$table->integer('user_id')->unsigned()->change();

마이그레이션을 되 돌리는 올바른 구문입니다.

$table->integer('user_id')->unsigned()->nullable(false)->change();

또는 원하는 경우 원시 쿼리를 작성할 수 있습니다.

public function down()
{
    /* Make user_id un-nullable */
    DB::statement('UPDATE `users` SET `user_id` = 0 WHERE `user_id` IS NULL;');
    DB::statement('ALTER TABLE `users` MODIFY `user_id` INTEGER UNSIGNED NOT NULL;');
}

이 답변이 도움이 되길 바랍니다. :)


4
이것은 L5에 대한 가장 완벽한 대답이지만 'user_id'가 외래 키인 경우 'DB :: statement ('SET FOREIGN_KEY_CHECKS)를 실행하지 않으면 변경할 수 없습니다. = 0 ');' 먼저. 완료되면 다시 1로 설정하십시오.
rzb

1
감사 nullable(false)때문에, 내 머리를 밖으로 당기는에서 저를 저장 nullable()잘 설명되지 않으며, 어떤이없는 notNull()기능.
잭 모리스

postgres가있는 외래 키에는 작동하지 않습니다. 시도 SET FOREIGN_KEY_CHECKS = 0하면 오류가 발생합니다. 원시 쿼리를 사용하여 테이블 제약 조건을 변경해야 할 수도 있습니다. 다음을 참조하십시오 : postgresql.org/docs/current/static/sql-altertable.html
rrrafalsz

이것은 내 테스트를 깨뜨리고 있습니다. 테스트가 시작된 다음 중단됩니다. 첫 번째 롤백이 원인이라고 생각합니다. MySQL 및 SQLite에 대한 테스트를 중단시킵니다.
Thomas Praxl

155

이미 데이터를 추가 한 열을 편집하려고한다고 가정하므로 데이터를 잃지 않고 열을 삭제하고 nullable 열로 다시 추가 할 수 없습니다. 우리는 alter기존 열입니다.

그러나 Laravel의 스키마 빌더는 열 이름 바꾸기 이외의 열 수정을 지원하지 않습니다. 따라서 다음과 같이 원시 쿼리를 실행해야합니다.

function up()
{
    DB::statement('ALTER TABLE `throttle` MODIFY `user_id` INTEGER UNSIGNED NULL;');
}

그리고 마이그레이션을 계속 롤백 할 수 있도록하기 위해 그렇게 할 down()것입니다.

function down()
{
    DB::statement('ALTER TABLE `throttle` MODIFY `user_id` INTEGER UNSIGNED NOT NULL;');
}

한 가지 참고 사항은 nullable과 nullable을 변환 할 수 없으므로 마이그레이션 전후에 데이터를 정리해야합니다. 따라서 마이그레이션 스크립트에서 두 가지 방법으로 수행하십시오.

function up()
{
    DB::statement('ALTER TABLE `throttle` MODIFY `user_id` INTEGER UNSIGNED NULL;');
    DB::statement('UPDATE `throttle` SET `user_id` = NULL WHERE `user_id` = 0;');
}

function down()
{
    DB::statement('UPDATE `throttle` SET `user_id` = 0 WHERE `user_id` IS NULL;');
    DB::statement('ALTER TABLE `throttle` MODIFY `user_id` INTEGER UNSIGNED NOT NULL;');
}

7
Laravel 4의 대체 query에 의해statement
면도기

2
감사합니다 @ Razor. 이에 따라 내 답변을 업데이트했습니다.
Unnawut

1
down두 번째 코드 블록 의 함수에서 SQL 문은로 끝나야합니다 NOT NULL. 합니다 ( down세 번째 예의 기능이 정확하다.)
스콧 웰던

46

그는 Laravel 5 의 완전한 마이그레이션입니다 .

public function up()
{
    Schema::table('users', function (Blueprint $table) {
        $table->unsignedInteger('user_id')->nullable()->change();
    });
}

public function down()
{
    Schema::table('users', function (Blueprint $table) {
        $table->unsignedInteger('user_id')->nullable(false)->change();
    });
}

요점은 인수 nullable로 전달 false하여 제거 할 수 있다는 것 입니다.



9

Laravel 5 이상과 마찬가지로 Dmitri Chebotarev의 답변에 추가하십시오.

교리 / dbal 패키지를 요구 한 후 :

composer require doctrine/dbal

그런 다음 다음과 같이 널 입력 가능 열을 사용하여 마이그레이션 할 수 있습니다.

public function up()
{
    Schema::table('users', function (Blueprint $table) {
        // change() tells the Schema builder that we are altering a table
        $table->integer('user_id')->unsigned()->nullable()->change();
    });
}

작업을 되돌리려면 다음을 수행하십시오.

public function down()
{
    /* turn off foreign key checks for a moment */
    DB::statement('SET FOREIGN_KEY_CHECKS = 0');
    /* set null values to 0 first */
    DB::statement('UPDATE `users` SET `user_id` = 0 WHERE `user_id` IS NULL;');
    /* alter table */
    DB::statement('ALTER TABLE `users` MODIFY `user_id` INTEGER UNSIGNED NOT NULL;');
    /* finally turn foreign key checks back on */
    DB::statement('SET FOREIGN_KEY_CHECKS = 1');
}

3

Dmitri Chebotarev 답변에 추가,

한 번에 여러 열을 변경하려면 다음과 같이 할 수 있습니다

DB::statement('
     ALTER TABLE `events` 
            MODIFY `event_date` DATE NOT NULL,
            MODIFY `event_start_time` TIME NOT NULL,
            MODIFY `event_end_time` TIME NOT NULL;
');


2

Laravel 4.2의 경우 위의 Unnawut의 답변이 가장 좋습니다. 그러나 테이블 접두사를 사용하는 경우 코드를 약간 변경해야합니다.

function up()
{
    $table_prefix = DB::getTablePrefix();
    DB::statement('ALTER TABLE `' . $table_prefix . 'throttle` MODIFY `user_id` INTEGER UNSIGNED NULL;');
}

그리고 마이그레이션을 계속 롤백 할 수 있도록하기 위해 그렇게 할 down()것입니다.

function down()
{
    $table_prefix = DB::getTablePrefix();
    DB::statement('ALTER TABLE `' . $table_prefix . 'throttle` MODIFY `user_id` INTEGER UNSIGNED NOT NULL;');
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.