Laravel迁移禁用外键检查的好方法

2022-08-30 10:11:01

在运行 laravel 迁移时,我遇到了一个小小的不便。我使用Laravel 5.1。

由于有很多表具有许多关系,因此我可能无法重命名迁移文件以使它们以正确的顺序运行,因此不会违反外键约束。这是我过去曾经做过的事情,而且非常不切实际。

我现在要做的是像这样定义每个迁移:

class CreateSomeTable extends Migration
{
    public function up()
    {
        DB::statement('SET FOREIGN_KEY_CHECKS=0;');
        // my table definitions go here
        DB::statement('SET FOREIGN_KEY_CHECKS=1;');
    }

    public function down()
    {
        DB::statement('SET FOREIGN_KEY_CHECKS=0;');
        // drop table
        DB::statement('SET FOREIGN_KEY_CHECKS=1;');
    }
}

这样做的问题是编写起来很乏味,并且会使代码变得混乱。

我还考虑过创建两个虚拟迁移文件,其唯一目的是启用和禁用外键检查,并且我会以这样的方式命名它们,即它们在每次迁移的开始和结束时运行。

如果有一个优雅的解决方案,是否有可能将其应用于播种过程,因为这往往也是一个问题。

这显然是一个非常即兴的解决方案,我问是否有更好的方法来做到这一点。有没有一些和方法可以覆盖或类似的东西?beforeMigrateafterMigrate

如果没有,你该怎么做?

任何见解都将不胜感激,我不喜欢我所说的所有选项。


答案 1

当Lumen / Laravel开始使用Passport时,我手头有类似的任务,我不得不放弃lucadegasperi/oauth2-server-laravel之前的oauth服务器实现。

我最终通过创建2个迁移来使事情顺利进行,其中第一个迁移清除外键,第二个迁移实际上删除表。

我不得不使用Laravel护照迁移之前的日期(2016-06-01),以便它们将在这些之前执行。

2016_05_31_000000_clear_old_oauth_relations.php

//...
class ClearOldOauthRelations extends Migration
{
    public function up()
    {
        Schema::disableForeignKeyConstraints();
        // drop foreign keys
        Schema::table('oauth_access_tokens', function (BluePrint $table) {
            $table->dropForeign('oauth_access_tokens_session_id_foreign');
        });
        //...
        Schema::enableForeignKeyConstraints();
    }
    //...
}

在第二个文件中2016_05_31_000001_clear_old_oauth.php

//...
public function up()
{
    Schema::disableForeignKeyConstraints();
    Schema::drop('oauth_access_tokens');
    //...
    Schema::enableForeignKeyConstraints();
}
//...

答案 2

我通过将外键逻辑提取到单独的迁移文件中来完成此操作。这有助于我:

  • 禁用外键约束。
  • 安全地删除数据库(如果存在)。

在代码中:

//file: 2017_06_19_230601_fk_postuser_table.php

public function down()
{
        Schema::disableForeignKeyConstraints();
        Schema::dropIfExists('post_user');
}

推荐