Laravel迁移变为使列可以为空

use*_*986 172 nullable laravel eloquent laravel-5 laravel-migrations

我用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();
}
Run Code Online (Sandbox Code Playgroud)

MUR*_*LAT 225

Laravel 5现在支持更换列..

官方文档的例子

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

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

Laravel 4不支持修改列.你必须编写raw 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();
        });               

}
Run Code Online (Sandbox Code Playgroud)

  • @algorhythm` - > nullable(false)`会让你再次更改列. (25认同)
  • 您需要要求doctrine\dbal迁移 (7认同)
  • - > change()要求您安装Doctrine DBAL包,并且它本身并不能识别laravel中开箱即用的所有相同列类型.例如,double不是DBAL认可的列类型. (6认同)
  • 谢谢你.但我怎么能反过来呢?如何将列更改为不可为空?有任何想法吗? (3认同)

小智 152

以下是未来读者的完整答案.请注意,这仅适用于Laravel 5+.

首先,你需要学说/ dbal包:

composer require doctrine/dbal
Run Code Online (Sandbox Code Playgroud)

现在,在迁移中,您可以执行此操作以使列可为空:

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();
    });
}
Run Code Online (Sandbox Code Playgroud)

您可能想知道如何还原此操作.遗憾的是,不支持此语法:

// Sadly does not work :'(
$table->integer('user_id')->unsigned()->change();
Run Code Online (Sandbox Code Playgroud)

这是还原迁移的正确语法:

$table->integer('user_id')->unsigned()->nullable(false)->change();
Run Code Online (Sandbox Code Playgroud)

或者,如果您愿意,可以编写原始查询:

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;');
}
Run Code Online (Sandbox Code Playgroud)

希望你会发现这个答案很有用.:)

  • 这是L5的最完整答案,但是应该指出的是,如果'user_id'是外键(应该是外键),则除非运行'DB :: statement('SET FOREIGN_KEY_CHECKS = 0');' 第一。完成后将其设置回1。 (3认同)
  • 谢谢,“nullable(false)”让我免于揪心,因为“nullable()”没有很好的文档记录,并且没有“notNull()”函数。 (3认同)

Unn*_*wut 150

我假设您正在尝试编辑已添加数据的列,因此在不丢失数据的情况下删除列并再次添加为可为空的列是不可能的.我们将alter现有专栏.

但是,Laravel的架构构建器不支持修改列,而不是重命名列.因此,您需要运行原始查询来执行它们,如下所示:

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

为了确保您仍然可以回滚迁移,我们也会这样做down().

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

需要注意的是,由于您要在可空和可空之间进行转换,因此您需要确保在迁移之前/之后清理数据.所以在迁移脚本中以这两种方式执行此操作:

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;');
}
Run Code Online (Sandbox Code Playgroud)

  • 对于Laravel 4,用`statement`替换`query` (7认同)
  • 这应该标记为正确的答案. (3认同)
  • 谢谢@Razor.相应更新了我的答案. (2认同)

Yau*_*hyk 40

他是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();
    });
}
Run Code Online (Sandbox Code Playgroud)

关键是,您可以nullable通过false作为参数传递来删除.


ken*_*ken 15

如果您碰巧更改了列并偶然发现了

'Doctrine\DBAL\Driver\PDOMySql\Driver' not found
Run Code Online (Sandbox Code Playgroud)

然后只需安装

composer require doctrine/dbal


Abd*_*una 11

我不得不使用nullable(true)

Schema::table('users', function($table)
{
    $table->string('name', 50)->nullable(true)->change();
});
Run Code Online (Sandbox Code Playgroud)


Fef*_*avi 8

安装作曲家包:

composer require doctrine/dbal
Run Code Online (Sandbox Code Playgroud)

成功安装 Composer 包后,我们可以使用迁移命令更改数据类型并更改列名称。

句法:

php artisan make:migration alter_table_[table_name]_change_[column_name] --table=[table_name]
Run Code Online (Sandbox Code Playgroud)

例子:

php artisan make:migration alter_table_sessions_change_user_id --table=sessions

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class AlterTableSessionsChangeUserId extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::table('sessions', function (Blueprint $table) {
            $table->integer('user_id')->unsigned()->nullable()->change();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::table('sessions', function (Blueprint $table) {
            $table->dropColumn('user_id');
        });
    }
}
Run Code Online (Sandbox Code Playgroud)

并运行:php artisan migrate

或者

或刷新表以更改列名称。不使用change方法。

Schema::create('throttle', function(Blueprint $table)
{
    $table->increments('id');
    # old code
    $table->integer('user_id')->unsigned();
    # new code
    $table->integer('user_id')->unsigned()->nullable();
}
Run Code Online (Sandbox Code Playgroud)

注意:以下命令用于清除表中的数据。

php artisan migrate:refresh --path=/database/migrations/2021_09_31_050851_create_throttle_table.php
Run Code Online (Sandbox Code Playgroud)


rzb*_*rzb 6

与Laravel 5+一样,增加了Dmitri Chebotarev的答案。

要求教义/ dbal软件包后:

composer require doctrine/dbal
Run Code Online (Sandbox Code Playgroud)

然后,您可以使用可为空的列进行迁移,如下所示:

composer require doctrine/dbal
Run Code Online (Sandbox Code Playgroud)

要还原操作,请执行以下操作:

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();
    });
}
Run Code Online (Sandbox Code Playgroud)


Adi*_*dil 2

尝试一下:

$table->integer('user_id')->unsigned()->nullable();
Run Code Online (Sandbox Code Playgroud)

  • 你在最后忘记了 `-&gt;change` 并仅在 Laravel 5+ 中提及它 (11认同)