删除外键出现问题

36

我的外键关联到它本身的表。这是为了生成具有层次结构的帖子

现在,当我尝试在数据库中删除该列时,它会给我以下错误:

1553 - Cannot drop index 'post_field_properties_parent_id_index': needed in a foreign key constraint

这是代码:

public function down()
{
        Schema::table( "post_field_properties", function( $table )
        {
            $table->dropForeign('parent_id');
            $table->dropColumn('parent_id');
        } );
}

我似乎唯一能做到的就是进入phpmyadmin并删除外键,然后删除该列。


你通过外键连接的表名是什么? - Nick Law
2
“parent_id” 真的是外键的名称吗?通常应该像这里所示的那样命名:http://laravel.com/docs/4.2/schema#foreign-keys。 - lukasgeiter
7个回答

53

我为自己的项目找到了解决方法。当你想要删除外键时,需要将表名和约束中的列连接起来,然后在名称后缀添加"_foreign"。

http://laravel.com/docs/5.1/migrations#foreign-key-constraints

public function down()
{
        Schema::table( "post_field_properties", function( $table )
        {
            $table->dropForeign('post_field_properties_parent_id_foreign');
            $table->dropColumn('parent_id');
        });
}

4
您可以选择性地通过将数组传递给dropForeign方法来指定要删除的外键列名:$table->dropForeign(['parent_id']);在删除相关列之前删除外键非常重要。 - Andrea Marco Sartori
2
可以确认这在Laravel 5.4.30中也适用。这个答案解决了我一些大问题 :)。 - Rob

16

以下是操作步骤:

  1. 登录数据库并查询外键关系的名称。如果您使用phpMyAdmin,请转到表格,点击“结构”选项卡,然后点击“关系视图”链接。

重要提示: 要查看“关系视图”,请确保您的表格“存储引擎”为InnoDB。如果不是,请参考此Q&A

等待几秒钟以使页面加载完成。搜索“约束名称”字段。例如:“contribution_copyright_id_foreign”。

  1. 进入Laravel迁移脚本(或创建一个)。诀窍是首先删除外键关系,然后再删除该列。

    public function down()

    {

         Schema::table('contribution', function(Blueprint $table){
    
             $table->dropForeign('contribution_copyright_id_foreign');
    
             $table->dropColumn('copyright_id');
    
         });
    

如果您想删除存在外键关系的表,您还需要先删除该外键关系。

来源:这里

希望对某些人有所帮助


4

这种方法已经被建议过了。https://dev59.com/nV8d5IYBdhLWcg3wmDOf#70510848 - miken32

4

我正在使用Laravel 8,结果发现我们可以使用dropConstrainedForeignId来实现这一点。因此,与另一个答案中提供的以下代码不同:

Schema::table( "post_field_properties", function( $table )
{
    $table->dropForeign('post_field_properties_parent_id_foreign');
    $table->dropColumn('parent_id');
});

你可以编写:

Schema::table( "post_field_properties", function( $table )
{
    $table->dropConstrainedForeignId('parent_id');
});

2

您可以在dropForeign()函数中传递外键数组,这样Laravel将自动在键名前添加表名并在其末尾添加“foreign”。

因此,请尝试在down()函数中使用以下代码:

 Schema::table('contribution', function(Blueprint $table){
     $table->dropForeign(['copyright_id']);
     $table->dropColumn('copyright_id');
 });

解释为什么这个答案比现有的答案更好会使它更有价值。这是一个7年前不可用的新功能吗?有没有文档可以链接到?您还应该根据问题中的标识符来定制您的答案。(另外,以“请尝试”开头的回答听起来像是猜测,而不是答案。) - miken32

1

要检查外键的名称,首先将您的数据库备份为.sql文件。

在那里您会看到您的外键名称如下:

...
KEY `employees_parent_id_foreign` (`parent_id`),
CONSTRAINT `employees_parent_id_foreign` FOREIGN KEY (`parent_id`) REFERENCES `laravel_article` (`id`) ON DELETE CASCADE
...

在我的情况下,使用的是Laravel 5.4, 它的格式如下:tablename_columnname_foreign 因此,在你的Laravel中(这里我尝试从员工表中删除外键)
Schema::table("employees", function( $table )
{
    $table->dropForeign('employees_parent_id_foreign');
    $table->dropColumn('parent_id');
});

0

尝试在列名称末尾加上“_foreign”。例如:

public function down()
{
        Schema::table( "post_field_properties", function( $table )
        {
            $table->dropForeign('parent_id_foreign');
            $table->dropColumn('parent_id');
        });
}

谢谢,我会尝试一下。 - Jimmyt1988
1
你的答案是错误的。你忘记了dropForeign的前缀,即表名。 - Binar Web

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