【发布时间】:2016-03-21 19:11:07
【问题描述】:
在运行 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;');
}
}
这样做的问题是写起来很乏味,而且代码混乱。
我还考虑过创建两个虚拟迁移文件,其唯一目的是启用和禁用外键检查,我会以这样的方式命名它们,以便它们在每个文件的开头和结尾运行迁移。
如果有一个优雅的解决方案,是否也可以将其应用到播种过程中,因为这往往也是一个问题。
这显然是一个非常即兴的解决方案,我想问是否有更好的方法来做到这一点。是否有一些我可以覆盖的 beforeMigrate 和 afterMigrate 方法或类似的方法?
如果没有,你会怎么做呢?
任何见解都将不胜感激,我不喜欢我所说的所有选项。
【问题讨论】:
-
如果您使用 artisan 创建迁移并且它们具有正确的时间戳,它们应该始终以正确的顺序运行。它们按照时间戳的顺序运行..
-
是的,这就是我提到文件顺序时的意思。问题是,有时你没有按正确的顺序生成它们,或者有时你可能有一个循环依赖,即两个表都有相互引用的外键。无论您以什么顺序运行该示例,除非您禁用检查,否则您将违反外键约束。
-
避免此问题的最佳方法是先创建一个表创建迁移,然后再创建一个创建/删除键的迁移。
-
不是特别相关,但您也可以通过这种方式禁用外键检查:
\DB::getSchemaBuilder()->disableForeignKeyConstraints()。不确定是否有更好的方法来调用此方法。 -
我又遇到了同样的问题,还有另一个项目。作为临时黑客,我正在按照 OP 中的建议进行操作; 2 个虚拟迁移文件,时间戳在其他所有操作之前和之后运行,分别关闭和打开外键检查。我认为 Laravel 的迁移系统存在根本缺陷。查看所有这些文件之间拆分的表创建代码既丑陋又不方便。从现在开始,我将把所有东西都放在一个迁移文件中,在开始和结束时禁用和启用外键检查,并且所有模式逻辑都清晰地排列在它们之间。