web-dev-qa-db-ja.com

列をNULL可能にするためのLaravel移行の変更

私は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();
}
151
user391986

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]) {

        case('5') :                
            Schema::table('pro_categories_langs', function(Blueprint $t) {
                $t->string('name', 100)->nullable()->default(null)->change();
            });               
            break;                
        /**
         * it is not L5 !!
         */
        default :                
             DB::statement('ALTER TABLE `pro_categories_langs` MODIFY `name` VARCHAR(100) NULL;');                                  
    }
191
MURATSPLAT

すでにデータを追加している列を編集しようとしているとします。そのため、データを失うことなく列をドロップして再度NULL入力可能列として追加することはできません。既存の列を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;');
}

1つの注意はあなたがnull許容とnot null許容の間で変換しているので、あなたがあなたの移行の前後にデータをきれいにすることを確実にする必要があるということです。それで、あなたの移行スクリプトで両方の方法でそれをしてください:

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;');
}
148
Unnawut

これは将来の読者のための完全な答えです。これはLaravel 5+でのみ可能です。

まず最初に、doctrine/dbalパッケージが必要です。

composer require doctrine/dbal

これで、マイグレーションで列をNULL可能にすることができます。

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;');
}

うまくいけば、あなたはこの答えが役に立つのがわかるでしょう。 :)

141

彼は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を削除できます。

36

たまたま列を変更してつまずいた場合

'Doctrine\DBAL\Driver\PDOMySql\Driver' not found

それからちょうどインストール

composer require doctrine/dbal

15
ken

Laravel 5+に関しては、Dmitri Chebotarevの答えに追加してください。

doctrine/dbalパッケージを要求した後:

composer require doctrine/dbal

そうすると、null許容列を使ってマイグレーションを行うことができます。

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
rzb

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;
');
3
Sameer

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;');
}
3
Debiprasad

それを試してみてください:

$table->integer('user_id')->unsigned()->nullable();
2
Adil