我使用无符号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();
}
答案 0 :(得分:191)
Laravel 5现在支持更改列..
官方文档
的示例Schema::table('users', function($table)
{
$table->string('name', 50)->nullable()->change();
});
来源: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]) {
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;');
}
答案 1 :(得分:148)
我假设您正在尝试编辑已添加数据的列,因此在不丢失数据的情况下,删除列并再次添加为可为空的列是不可能的。我们将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;');
}
需要注意的是,由于您要在可空和可空之间进行转换,因此您需要确保在迁移之前/之后清理数据。因此,请在迁移脚本中以两种方式执行此操作:
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;');
}
答案 2 :(得分:138)
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 :(得分:36)
他是 Laravel 5 的完整迁移:
nullable
关键是,您可以通过传递false
作为参数来删除 while (isspace(*end)) {
end++;
}
。
答案 4 :(得分:14)
如果您碰巧更改了列并偶然发现了
'Doctrine\DBAL\Driver\PDOMySql\Driver' not found
然后只需安装
composer require doctrine/dbal
答案 5 :(得分: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;
');
答案 6 :(得分:3)
加入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');
}
答案 7 :(得分:3)
对于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;');
}
答案 8 :(得分:2)
试一试:
$table->integer('user_id')->unsigned()->nullable();