在开发中,我在laravel中遇到了很多迁移问题.
我创建了一个迁移.当我完成创建时,在迁移过程中(例如,外键约束)会出现一个小错误,导致"php artisan migrate"失败.他确实告诉我错误的位置,然后迁移到一个不一致的状态,在错误发生之前对数据库进行了所有修改,而不是下一个.
这使得当我修复错误并重新运行migrate时,第一个语句失败,因为已经创建/修改了列/表.然后我知道的唯一解决方案是进入我的数据库并手动"回滚"所有内容,这样做的时间更长.
migrate:rollback尝试回滚以前的迁移,因为当前未成功应用当前迁移.
我还试图将我的所有代码都包装到DB :: transaction()中,但它仍然不起作用.
这有什么解决方案吗?或者我只需要手动回滚东西?
编辑,添加一个示例(不编写Schema构建器代码,只是某种伪代码):
Migration1:
Create Table users (id, name, last_name, email)
Migration1执行正常.几天后我们进行迁移2:
Create Table items (id, user_id references users.id) Alter Table users make_some_error_here
现在将会发生的事情是,migrate将调用第一个语句,并使用外键向用户创建表项.然后,当他试图应用下一个语句时,它将失败.
如果我们修复了make_some_error_here,我们就无法运行migrate,因为它创建了表"items".我们无法回滚(也不刷新,也不能重置),因为我们无法删除表用户,因为表项中存在外键约束.
然后,继续的唯一方法是转到数据库并手动删除表项,以便以一致的状态迁移.
这不是Laravel限制,我打赌你使用MYSQL,对吧?
正如MySQL文档说这里
某些语句无法回滚.通常,这些语句包括数据定义语言(DDL)语句,例如创建或删除数据库的语句,创建,删除或更改表或存储例程的语句.
我们有泰勒Otwell自己的建议在这里说:
我最好的建议是每次迁移执行一次操作,以便您的迁移保持非常精细.
我正在使用MySql,但遇到了这个问题。
我的解决方案取决于您的down()
方法完全可以完成您的工作,up()
但要倒退。
这就是我要去的:
try{ Schema::create('table1', function (Blueprint $table) { //... }); Schema::create('tabla2', function (Blueprint $table) { //... }); }catch(PDOException $ex){ $this->down(); throw $ex; }
因此,如果出现故障,这里会自动调用该down()
方法并再次引发异常。
而不是使用两次transaction()
尝试之间的迁移