原则迁移:如何避免在postUp步骤中出现SQL错误?

MatjažDrolc

在部署使用Doctrine ORM的Symfony2应用程序时,您如何处理迁移?

我一直在使用DoctrineMigrationsBundle。如果您避免尝试在迁移的postUp()部分中使用实体,则它会很好地工作。但是,如果这样做,就会遇到麻烦。

以下是一些伪代码来说明问题:

/* Migration1.php */
class Migration1 extends... implements ContainerAwareInterface {
    public function up(...) {
        query("CREATE TABLE entities WITH COLUMNS col1, col2;");
    }

    public function postUp(...) {
        $e = new Entity();
        $e->setCol1("value1");
        $e->setCol2("value2");
        $entityManager->persist($e);
    }
}


/* Migration2.php */
class Migration2 extends... implements ContainerAwareInterface {
    public function up(...) {
        query("ALTER TABLE entities ADD col3");
    }
}

实际案例1:

  • 开发人员更改应用程序代码并准备Migration1
  • 代码已部署在服务器上,包括运行迁移
  • 开发人员更改应用程序代码并准备进行Migration2
  • 代码已部署在服务器上,包括运行迁移

一切都很好。

实际案例2:

  • 开发人员更改应用程序代码并准备Migration1
  • 开发人员更改应用程序代码并准备进行Migration2
  • 代码已部署在服务器上,包括运行迁移

这是行不通的。为什么?

Migration1的postUp()部分中的代码将与最新的应用程序代码一起运行。这意味着Doctrine ORM将期望col3已经存在于实体表中。但是,由于Migration2尚未运行到那时,因此没有字段col3。尝试在Migration1中保留新实体会导致SQL错误。

我提出了两个解决此问题的想法:

  • 部署新代码时,请使用版本控制系统。分别检出每个提交,在每个提交中运行迁移,直到获得最新的提交为止,或者
  • 不要使用postUp()更改实体。完成数据库的所有结构更改后,请使用单独的脚本处理实体。

请评论您在该问题上的经验,并说明您如何处理。我敢肯定你们中的一些人在实践中遇到过这种情况。

阿德·玛蒂森(Aad Mathijssen)

您完美描述的场景表明,在一般情况下,无法在“教义迁移”中使用实体。

因此,恐怕要以一种健壮的方式进行这项工作的唯一方法是降到DBAL级别:

public function postUp(...) {
    $this->connection->insert('entities', [
        'col1' => 'value1',
        'col2' => 'value2'
    ]);
}

通过使用DBAL查询,将直接提供要使用的列,而不是通过应用程序代码定义的实体(而不需要与当前表结构同步)间接提供。

另请参见“如何在Symfony中使用Doctrine迁移”一文的第4.2节,该节还描述了在Doctrine Migrations中使用实体时出现的问题,尤其是以下引号:

不要在迁移中使用实体,您一定不要依赖实体(PHP)代码,而只能依赖数据库!

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

如何避免迁移时出现错误1146?

如何避免在View中出现ModeState无效属性错误

如何避免Postgresql的FOR循环中出现语法错误?

如何避免在Shiny R图中出现闪烁错误?

如何避免 Flutter EpubViewer 中出现此错误?

如何避免近乎同步的SQL添加中出现重复的行?

Oracle Sql:如何避免结果中出现重复?

django:如何避免迁移时出现权限错误

SQL Server的副本-SSAS步骤中的SSIS作业中出现错误

如何避免在R中出现循环?

如何避免在RRDTool图表中出现空格?

如何避免checkListBox中出现重复项

如何避免在MySQL查询中出现重复?

如何避免联接查询中出现多行?

如何避免RabbitMQ中出现重复消息?

如何避免在使用GNU Parallel的Bash脚本中出现SIGCHLD错误

在某些元素中插入 ElementTree 时,如何避免在生成的 XML 文件中出现错误缩进?

如何避免在magento安装中出现“必须加载PHP扩展“ 0””错误?

我应该如何接受输入以避免代码中出现以下错误?

如何避免JavaScript中出现“超出最大调用堆栈大小”错误?

如何避免 RDS 实例和安全组的模块中出现循环错误

如何避免在“ with”语句中匹配所有“ else”的Dialyzer中出现“永不匹配”错误?

如何避免在Airbnb ESLint中出现“箭头函数期望返回值”错误

刷新页面时,如何避免部署的 React 应用程序中出现 404 错误?

为什么在Laravel迁移中出现引用错误?

避免pd.to_datetime在熊猫中出现错误

避免在拉取请求中出现无用的策略错误?

循环时避免在Python中出现索引错误

使用sql的Android Studio中出现错误