Laravel迁移改变并使列可以空

我用user_id unsigned创build了一个迁移。 我怎样才能编辑user_id在一个新的模式也使其为nullable()

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

我假设你正在编辑一个已经添加了数据的列,所以删除列并添加一个空数据列是不可能的,而不会丢失数据。 我们将alter现有的列。

但是,Laravel的架构构build器不支持修改除重命名列之外的列。 所以你需要运行原始查询来完成它们,如下所示:

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

有一点需要注意的是,由于您在可空和不可空的情况下进行转换,因此您需要确保在迁移之前/之后清理数据。 所以,在你的迁移脚本中这样做:

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

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

这是未来读者的完整答案。 请注意,这只能在Laravel 5+中使用。

首先你需要doctrine / 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(); }); } 

你可能想知道如何恢复这个操作。 可悲的是这个语法不被支持:

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

希望你会发现这个答案有用。 🙂

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

重点是,您可以通过传递false作为参数来删除nullable

如果你碰巧改变了列,并偶然发现

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

然后安装

composer require doctrine/dbal

添加到Dmitri Chebotarev的答案,至于Laravel 5+。

在要求doctrine / 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'); 

}

尝试一下:

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

添加到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; ');