我用unsigned user_id创建了一个迁移。我如何编辑user_id在一个新的迁移,也使它为空()?
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();
}
我假设您正在尝试编辑一个已经添加了数据的列,因此在不丢失数据的情况下,删除列并作为可空列再次添加是不可能的。我们将修改现有的列。
但是,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;');
}
对于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;');
}
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]) {
// 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();
});
}
注意,这只在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;');
}