Laravel迁移 - 删除列

24

我需要从数据库表 clients 中删除列 UserDomainName

最初我通过执行 composer require doctrine/dbal 然后执行 composer update 安装了 doctrine/dbal,如文档所述。

然后我创建了要用于删除该列的迁移:

php artisan make:migration remove_user_domain_name_from_clients --table=clients

我在down()方法中添加了Schema::dropColumn('UserDomainName');:

<?php

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

class RemoveDomainName extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::table('clients', function (Blueprint $table) {
            //
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::table('clients', function (Blueprint $table) {
            Schema::dropColumn('UserDomainName');
        });
    }
}

然而,我得到

Migrating: 2017_08_22_135145_remove_user_domain_name_from_clients
Migrated:  2017_08_22_135145_remove_user_domain_name_from_clients

执行php artisan migrate后没有删除列。如果再次执行,会得到Nothing to migrate.的提示。


为什么你把 dropColumn 添加到 down 方法中?它不应该是 up 方法的一部分吗? - undefined
4个回答

78

down函数用于回滚操作,您需要在up函数中添加dropColumn,因为这是在运行迁移时要执行的操作。

因此,在您的up函数中应该包含:

Schema::table('clients', function (Blueprint $table) {
    $table->dropColumn('UserDomainName');
});

down 函数中,您应该执行相反操作,将列重新添加回去:

Schema::table('clients', function (Blueprint $table) {
    $table->string('UserDomainName');
});

这样,您可以随时返回到迁移中的任何一个点。


4
我认为 dropIfExists 函数仅适用于整个表格。 - Jerodev
谢谢!我尝试了一下,现在出现了Call to undefined method Illuminate\Database\Schema\MySqlBuilder::dropColumn()的错误。我会尝试解决这个问题,然后再尝试您的解决方案。 - Black
1
你用过我发布的代码吗?因为在你的例子中,你是在Schema类上静态使用函数,这样是行不通的。 - Jerodev
3
不要使用 dropIfExists('column') 以免删除整张表格!@Jeff - Positivity
这样,你可以随时返回到迁移的任何一点。 这不是真的。如果你删除了一列,你就无法恢复数据。另外要记住,如果你尝试添加一个非空字段,查询将失败。 - undefined

0

解决方案1:使用一行代码的解决方案

此解决方案已在Laravel 9.x上进行了测试,可能无法在较低版本中使用

在迁移文件的down方法中使用Schema::dropColumns方法,第一个参数将是表名,第二个参数将是您想要以数组形式删除的列名。

public function down()
{
    Schema::dropColumns("tablename", ["column"]);
}

参考

解决方案2:另一种方法

在这里,$table->dropColumn 可以接受数组或字符串形式的列名。

public function down()
{
    Schema::table("tablename", function (Blueprint $table) {
        $table->dropColumn(['columnname']);
        // OR 
        $table->dropColumn('columnname');
    });
}

@Pathros 对不起,已经相应地更新了。谢谢。 - Bedram Tamang
刚在v9.41上进行了测试,dropColumns()可以正常工作,但dropColumn()无法正常工作。 - Rikki Masters
存在两个函数:dropColumnsdropColumn - Bedram Tamang
那么命令是什么?php artisan migrate:refresh - t q

-1
我试过这个,它有效。
    public function up()
{
    if (Schema::hasColumn('your_table_name', 'column_name_to_remove')) {
        Schema::table('your_table_name', function (Blueprint $table) {
            $table->dropColumn('column_name_to_remove');
        });
    }
}

请不要重复已有的答案,除非你想分享新的见解。如果是这种情况,请在你的答案中加入一些解释,以便其他人可以从中学习。 - undefined

-5
删除列,您可以这样做:
在您的 down 函数中应该有以下内容:
 public function down()
    {
        Schema::table('products', function (Blueprint $table) {
            $table->dropColumn('UserDomainName');
        });
    }

然后运行

php artisan migrate:rollback

就这样。


我认为这不应该放在down方法中。 - OsDev

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接