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

foreign key constraint: cannot drop table because other objects depend on it

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

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

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

Postgres 不提供这个。

在 运行 向下迁移中,出现错误:

Dependent objects still exist: 7 ERROR: cannot drop table table2 because other objects depend on it

DETAIL: constraint table1_table2_table1_id_foreign on table table1_table2 depends on table table2

HINT: Use DROP ... CASCADE to drop the dependent objects too. (SQL: drop table "table2")

问题:这个投诉对我来说很好奇,因为我在外键创建上设置了->onDelete('cascade');。为什么会这样?

片段:

创建 Table1 Table:

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

创建 Table2 Table(在 table 1 次迁移后调用):

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

创建外键Table(要调用的最后一次迁移)

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');
    });
    ...
}

This complaint is curious to me as I set ->onDelete('cascade'); on the foreign key creations. Why is this happening?

此处的关键术语是 "on delete" - 当您 中删除一行 table 时,该选项将确定具有外键的行是否引用 该行 也将被删除。

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

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

关键语录:

When you create complex database structures involving many tables with foreign key constraints, views, triggers, functions, etc. you implicitly create a net of dependencies between the objects. For instance, a table with a foreign key constraint depends on the table it references.

和:

if you do not want to bother deleting all the dependent objects individually, you can run DROP TABLE products CASCADE; and all the dependent objects will be removed, as will any objects that depend on them, recursively. In this case, it doesn't remove the orders table, it only removes the foreign key constraint.

和:

Almost all DROP commands in PostgreSQL support specifying CASCADE.

对于我的情况;您可能会在这种情况下遇到此错误;

如果您的 table 似乎在迁移 table 中回滚(例如:可能第一次忘记删除功能)但 table 仍然存在于数据库中,您可能会收到此错误。 migrate:fresh 命令将失败并显示此场景的给定错误消息。

您可以手动删除 table 或使用该迁移名称向迁移 table 添加一行,一切都会正常进行。