Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/laravel/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php Laravel迁移是禁用外键检查的好方法_Php_Laravel_Migration - Fatal编程技术网

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

Php Laravel迁移是禁用外键检查的好方法,php,laravel,migration,Php,Laravel,Migration,在运行laravel迁移时,我面临着一个小小的不便。我使用的是Laravel5.1 由于有许多表具有许多关系,因此我可能不可能重命名迁移文件,使其以正确的顺序运行,因此不会违反外键约束。这是我过去做过的一次,非常实际 我现在要做的是如下定义每个迁移: class CreateSomeTable extends Migration { public function up() { DB::statement('SET FOREIGN_KEY_CHECKS=0;');

在运行laravel迁移时,我面临着一个小小的不便。我使用的是Laravel5.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;');
    }
}
这样做的问题是编写起来很乏味,而且代码也很混乱

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

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

这显然是一个非常即兴的解决方案,我想知道是否有更好的方法。是否有一些在迁移之前和迁移之后的
方法可以覆盖,或者类似的方法

如果没有,你怎么做呢


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

当Lumen/Laravel开始使用Passport时,我手头有一个类似的任务,我不得不放弃以前的oauth服务器实现

最后,我创建了两个迁移,第一个迁移清除外键,第二个迁移实际删除表

我必须使用(2016-06-01)迁移之前的日期,因此它们将在迁移之前执行

2016\u 05\u 31\u000000\u clear\u old\u oauth\u 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();
    }
    //...
}
//...
public function up()
{
    Schema::disableForeignKeyConstraints();
    Schema::drop('oauth_access_tokens');
    //...
    Schema::enableForeignKeyConstraints();
}
//...
在第二个文件中
2016\u 05\u 31\u000001\u clear\u old\u oauth.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();
    }
    //...
}
//...
public function up()
{
    Schema::disableForeignKeyConstraints();
    Schema::drop('oauth_access_tokens');
    //...
    Schema::enableForeignKeyConstraints();
}
//...

我通过将外键逻辑提取到一个单独的迁移文件中来实现这一点。这帮助我:

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

//file: 2017_06_19_230601_fk_postuser_table.php

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

另一个需要记住的重要方面是先删除foreignKey,然后删除列。删除列首先会引发错误:

无法删除索引“tableName\u columnName\u foreign”:外键约束中需要索引

正确的顺序很重要:

    public function down()
    {
        Schema::table('tableName', function (Blueprint $table) {
            $table->dropForeign(['columnName']); // fk first

            $table->dropColumn('columnName'); // then column
        });
    }

如果使用artisan创建迁移,并且它们具有正确的时间戳,则它们应始终以正确的顺序运行。它们按时间戳的顺序运行……是的,这就是我提到文件顺序时的意思。问题是,有时您没有按照正确的顺序生成它们,或者有时您可能存在循环依赖关系,即两个表都有相互引用的外键。无论以何种顺序运行该示例,除非禁用检查,否则都会出现外键约束冲突。避免此问题的最佳方法是先创建表,然后创建另一个创建/删除键的迁移。不特别相关,但是您也可以通过这种方式禁用外键检查:
\DB::getSchemaBuilder()->disableForeignKeyConstraints()
。不确定是否有更好的方法调用此方法。我又遇到了完全相同的问题,还有另一个项目。作为一名临时黑客,我完全按照OP中的建议行事;2个时间戳为在所有其他操作之前和之后运行的虚拟迁移文件,分别关闭和打开外键检查。我相信拉威尔的移民体系存在根本缺陷。查看所有这些文件之间拆分的表创建代码既难看又不方便。从现在起,我将把所有内容都放在一个迁移文件中,在开始和结束时禁用和启用外键检查,并在它们之间清楚地列出所有模式逻辑。这真是太好了!这是最近才添加的,还是已经在laravel中添加了一段时间,但当我遇到这个问题时我没有注意到?嗨@Pavlin,我不知道这是什么时候在laravel/Lumen中添加的。请注意,您需要在例如PhpMyAdmin(结构->关系)中查找外键约束的名称,这是自5.2版以来添加到Laravel的