Laravel迁移事务

oli*_*ra1 19 php migrate laravel

在开发中,我在laravel中遇到了很多迁移问题.

我创建了一个迁移.当我完成创建时,在迁移过程中(例如,外键约束)会出现一个小错误,导致"php artisan migrate"失败.他确实告诉我错误的位置,然后迁移到一个不一致的状态,在错误发生之前对数据库进行了所有修改,而不是下一个.

这使得当我修复错误并重新运行migrate时,第一个语句失败,因为已经创建/修改了列/表.然后我知道的唯一解决方案是进入我的数据库并手动"回滚"所有内容,这样做的时间更长.

migrate:rollback尝试回滚以前的迁移,因为当前未成功应用当前迁移.

我还试图将我的所有代码都包装到DB :: transaction()中,但它仍然不起作用.

这有什么解决方案吗?或者我只需要手动回滚东西?



编辑,添加一个示例(不编写Schema构建器代码,只是某种伪代码):
Migration1:

Create Table users (id, name, last_name, email)
Run Code Online (Sandbox Code Playgroud)

Migration1执行正常.几天后我们进行迁移2:

Create Table items (id, user_id references users.id)
Alter Table users make_some_error_here
Run Code Online (Sandbox Code Playgroud)

现在将会发生的事情是,migrate将调用第一个语句,并使用外键向用户创建表项.然后,当他试图应用下一个语句时,它将失败.

如果我们修复了make_some_error_here,我们就无法运行migrate,因为它创建了表"items".我们无法回滚(也不刷新,也不能重置),因为我们无法删除表用户,因为表项中存在外键约束.

然后,继续的唯一方法是转到数据库并手动删除表项,以便以一致的状态迁移.

Yev*_*yev 15

这不是Laravel限制,我打赌你使用MYSQL,对吧?

正如MySQL文档说这里

某些语句无法回滚.通常,这些语句包括数据定义语言(DDL)语句,例如创建或删除数据库的语句,创建,删除或更改表或存储例程的语句.

我们有泰勒Otwell自己的建议在这里说:

我最好的建议是每次迁移执行一次操作,以便您的迁移保持非常精细.


Gui*_*n04 5

我正在使用MySql,但遇到了这个问题。

我的解决方案取决于您的down()方法完全可以完成您的工作,up() 但要倒退。

这就是我要去的:

try{
    Schema::create('table1', function (Blueprint $table) {
        //...
    });
    Schema::create('tabla2', function (Blueprint $table) {
        //...
    });
}catch(PDOException $ex){
    $this->down();
    throw $ex;
}
Run Code Online (Sandbox Code Playgroud)

因此,如果出现故障,这里会自动调用该down()方法并再次引发异常。

而不是使用两次transaction()尝试之间的迁移


DaG*_*ner 1

只需从迁移文件中删除失败的代码并为失败的语句生成新的迁移即可。现在,当它再次失败时,数据库的创建仍然完好无损,因为它位于另一个迁移文件中。

使用此方法的另一个优点是,您在恢复数据库时拥有更多的控制权和更小的步骤。

希望有帮助:D

  • 这是一个解决方法。但是进行多种操作的迁移也很有用,我不希望单个数据库更改有 10 个文件。受您答案的启发,我现在所做的是,当我在迁移过程中遇到错误时,只需注释掉所有正确执行的部分即可。修复错误后,我会取消注释,然后回滚并再次迁移以重新检查一切正常。这和你说的效果差不多,但没有创建更多文件。仍然是一个解决方法。 (12认同)