外键约束:不能删除表,因为其他对象依赖于它

时间:2018-05-14 21:29:37

标签: laravel postgresql laravel-5.1

我正在Laravel 5.1上运行迁移,并且正在将数据库从Mysql切换到Postgres。

通常我可以在运行down迁移之前将外键检查设置为0:

- DB::statement('SET FOREIGN_KEY_CHECKS = 0');
- Do stuff
- DB::statement('SET FOREIGN_KEY_CHECKS = 1');

Postgres不提供这个。

在减少迁移时,我收到错误:

  

依赖对象仍然存在:7错误:无法删除表table2,因为其他对象依赖于它

     

详细说明:表table1_table2上的约束table1_table2_table1_id_foreign取决于表table2

     

提示:使用DROP ... CASCADE也可以删除相关对象。 (SQL:drop table“table2”)

问题:当我在外键创作上设置->onDelete('cascade');时,此投诉对我很好奇。为什么会这样?

片断:

创建Table1表:

...
public function down()
{
    Schema::drop('table1_table2');
    Schema::drop('table1'); 
}

创建Table2表(在表1迁移后调用):

...
public function down()
{
    Schema::drop('table2'); 
}

创建外键表(要调用的上次迁移)

public function up()
{
  Schema::table('table1_table2', function(Blueprint $table)
  {
    $table->foreign('table1_id')->references('id')->on('table1')->onDelete('cascade');
    $table->foreign('table2_id')->references('id')->on('table2')->onDelete('cascade');
  });
  ...
 }

public function down()
{
    ...
    Schema::table('table1_table2', function(Blueprint $table)
    {
        $table->dropForeign('table1_id');
        $table->dropForeign('table2_id');
    });
    ...
}

2 个答案:

答案 0 :(得分:5)

  

当我设置时,这个投诉对我很好奇 - > onDelete('cascade');关于外国创作。为什么会这样?

此处的关键术语是“在删除时” - 当您从一个表中删除行时,该选项将确定具有引用该行的外键的行是否为也删除了。

但是,您的更改脚本不是删除行,而是删除表。因此,这是一个不同的事件,不受外键上ON DELETE选项的影响。

提示中提到的CASCADEDROP TABLE语句discussed in the manual under "Dependency Tracking"上的关键字:

关键引号:

  

当您创建涉及许多具有外键约束,视图,触发器,函数等的表的复杂数据库结构时,您隐式地创建了对象之间的依赖关系网。例如,具有外键约束的表取决于它引用的表。

  

如果您不想单独删除所有依赖对象,则可以运行DROP TABLE products CASCADE;并删除所有依赖对象,递归依赖于依赖它们的任何对象。在这种情况下,它不会删除orders表,它只删除外键约束。

  

PostgreSQL中的几乎所有DROP命令都支持指定CASCADE。

答案 1 :(得分:0)

就我而言;在这种情况下,您会收到此错误;

如果您的表似乎已在迁移表中回滚(例如:可能是第一次忘记了drop函数),但该表仍存在于数据库中,则可能会出现此错误。在这种情况下,migrate:fresh命令将失败,并显示错误消息。

您可以手动删除表或使用该迁移名称在迁移表中添加一行,然后一切正常。