【问题标题】:Doctrine migrations: How to avoid SQL errors in the postUp step?教义迁移:如何避免 postUp 步骤中的 SQL 错误?
【发布时间】:2016-02-20 21:31:38
【问题描述】:

在部署使用 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");
    }
}

实际案例一:

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

一切正常。

实际案例2:

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

这不起作用。为什么?

Migration1 的 postUp() 部分中的代码将使用最新的应用程序代码运行。这意味着 Doctrine ORM 将期望 col3 已经存在于实体表中。但是,由于 Migration2 到那时还没有运行,所以没有字段 col3。尝试在 Migration1 中持久化新实体会导致 SQL 错误。

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

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

请就您在该问题上的经验发表评论,并说明您是如何处理它的。我相信你们中的一些人在实践中遇到过这种情况。

【问题讨论】:

  • 难道不专门使用 Up() 方法也能解决这个问题吗?
  • 并非如此。在某些情况下,您可能希望在应用程序中使用仅在 postUp() 部分中可用的其他服务。

标签: php git entity-framework symfony doctrine-orm


【解决方案1】:

您完美描述的场景表明(通常)不可能在 Doctrine Migrations 中使用实体。

所以恐怕要使这项工作以稳健的方式工作的唯一方法是下降到 DBAL 级别:

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

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

另请参阅"How to work with Doctrine migrations in Symfony" post 的第 4.2 节,其中还描述了在 Doctrine Migrations 中使用实体的问题,尤其是以下引用:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-11-14
    • 1970-01-01
    • 2020-02-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-19
    相关资源
    最近更新 更多