Laravel Migration Change to Make a Column Nullable

喜你入骨 提交于 2019-11-26 23:54:41

问题


I created a migration with unsigned user_id. How can I edit user_id in a new migration to also make it 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();
}

回答1:


Laravel 5 now supports changing a column; here's an example from the offical documentation:

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

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

Laravel 4 does not support modifying columns, so you'll need use another technique such as writing a raw SQL command. For example:

// 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();
        });               

}



回答2:


Here's the complete answer for the future reader. Note that this is only possible in Laravel 5+.

First of all you'll need the doctrine/dbal package:

composer require doctrine/dbal

Now in your migration you can do this to make the column 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();
    });
}

You may be wondering how to revert this operation. Sadly this syntax is not supported:

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

This is the correct syntax to revert the migration:

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

Or, if you prefer, you can write a raw query:

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

Hopefully you'll find this answer useful. :)




回答3:


I assume that you're trying to edit a column that you have already added data on, so dropping column and adding again as a nullable column is not possible without losing data. We'll alter the existing column.

However, Laravel's schema builder does not support modifying columns other than renaming the column. So you will need to run raw queries to do them, like this:

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

And to make sure you can still rollback your migration, we'll do the down() as well.

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

One note is that since you are converting between nullable and not nullable, you'll need to make sure you clean up data before/after your migration. So do that in your migration script both ways:

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



回答4:


He're the full migration for 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();
    });
}

The point is, you can remove nullable by passing false as an argument.




回答5:


If you happens to change the columns and stumbled on

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

then just install

composer require doctrine/dbal




回答6:


Adding to Dmitri Chebotarev's answer, as for Laravel 5+.

After requiring the doctrine/dbal package:

composer require doctrine/dbal

You can then make a migration with nullable columns, like so:

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

To revert the operation, do:

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



回答7:


Adding to Dmitri Chebotarev Answer,

If you want to alter multiple columns at a time , you can do it like below

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



回答8:


Try it:

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



回答9:


For Laravel 4.2, Unnawut's answer above is the best one. But if you are using table prefix, then you need to alter your code a little.

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

And to make sure you can still rollback your migration, we'll do the down() as well.

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


来源:https://stackoverflow.com/questions/24419999/laravel-migration-change-to-make-a-column-nullable

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!