【问题标题】:laravel migrations leave DB in an invalid statelaravel 迁移使数据库处于无效状态
【发布时间】:2018-11-16 19:10:08
【问题描述】:

如果迁移由于任何原因(例如拼写错误)中途失败,它会提交一半的迁移,而忽略其余部分。它似乎并没有尝试回滚它刚刚所做的事情。(通过回滚包含事务或调用 down())

如果您尝试手动回滚上次迁移,例如php artisan migrate:rollback --step=1,它只回滚上次迁移之前的迁移,即失败之前的迁移。

考虑这种迁移:

public function up()
{
    DB::table('address')->insert(['id'=>1,'street'=>'Demo', 'country_id'=>83]);
    DB::table('customer')->insert(['id'=>1,'username'=>'demo','address_id'=>1]);
}

public function down()
{
    DB::table('customer')->where('id',1)->delete();
    DB::table('address')->where('id',1)->delete();
}

如果客户的插入失败(例如我们忘记设置非空列、错字或不应该存在的记录),则插入地址记录。

migrate:rollback 不会回滚此迁移,它会回滚之前的迁移,并且我们会留下虚假的孤立地址记录。显然我们可以放弃重新创建数据库并从头开始运行迁移,但这不是重点 - 迁移不应该让一半的迁移完成并且数据库处于无效状态。

有解决办法吗?例如可以将事务放入迁移中,使其全部插入或不插入吗?

如果我们在半完成迁移失败后查看迁移表,它不存在。

注意:我们使用迁移来插入(和修改/删除)应用程序运行所需的静态数据。它不是开发数据或测试数据。例如。国家数据、货币数据,以及管理操作员等。

【问题讨论】:

  • 我从未尝试过添加交易,但它可能会奏效。下次我可能不得不尝试,而不是在回滚/迁移时不断注释行。

标签: php laravel migration


【解决方案1】:

您应该在事务中运行这些迁移:

DB::transaction(function () {
    // Your code goes here.
}

或者您可以使用 try/catch 块:

try {
    DB::beginTransaction();

     // Your code goes here ...

    DB::commit();
} catch(\Exception $e) {
    DB::rollBack();
}

【讨论】:

  • 太棒了,这行得通。我在我的主代码中使用了这两种形式的事务,但是迁移数据库语法与雄辩的文档完全不同,一直是个谜——我们只能从网络上的示例和/或猜测中综合它。跨度>
  • 另外,我相信您可以通过在迁移中导入 DatabaseMigrations 特征来完成我在评论中提到的内容。
  • 嗨,你知道我在哪里可以找到关于 DatabaseMigrations 特征的文档(它是什么,如何使用等)。谷歌只是在寻找错误报告和单元测试讨论。
猜你喜欢
  • 2021-12-17
  • 2018-11-14
  • 2014-06-05
  • 2019-04-25
  • 2019-01-19
  • 2019-04-16
  • 2018-04-04
  • 2020-05-07
  • 1970-01-01
相关资源
最近更新 更多