在开发时,我遇到了太多关于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“。我们不能回滚(也不能刷新,也不能重置),因为我们不能删除表users,因为表项中有一个外键约束。
然后,继续的唯一方法是转到数据库并手动删除表项,以获得一致状态的迁移。
发布于 2015-11-18 10:40:55
这不是Laravel的限制,我打赌你用的是MYSQL,对吧?
正如MYSQL文档所说的那样,here
某些语句无法回滚。通常,这些语句包括数据定义语言(DDL)语句,如创建或删除数据库的语句、创建、删除或更改表或存储例程的语句。
我们有一个泰勒·奥特威尔本人的推荐,here说:
我最好的建议是每次迁移都执行一次操作,这样您的迁移就可以保持非常细粒度。
-更新--
不要担心!
最佳实践如下:
你永远不应该做出破坏性的改变。
这意味着,在一个部署中,您可以创建新的表和字段,并部署使用它们的新版本。在下一次部署中,您将删除未使用的表和字段。
现在,即使您在这两个部署中都会遇到问题,如果迁移失败,也不用担心,工作版本无论如何都会使用函数式数据结构。使用每次迁移的单一操作,您很快就会发现问题。
发布于 2016-12-09 06:59:52
我正在使用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()之间进行迁移
发布于 2015-12-21 21:34:53
与Yevgeniy一样,Afanasyev强调了Taylor Otwell的话(但我自己已经采用了一种方法):让您的迁移只在特定的表上工作,或者执行特定的操作,例如添加/删除列或键。这样,当您获得导致不一致状态的失败迁移时,您只需删除该表并再次尝试迁移即可。
我已经经历了你所描述的问题,但到目前为止还没有找到解决它的方法。
https://stackoverflow.com/questions/20420600
复制相似问题