gpt4 book ai didi

php - 学说迁移 : How to avoid SQL errors in the postUp step?

转载 作者:搜寻专家 更新时间:2023-10-31 21:04:07 24 4
gpt4 key购买 nike

在部署使用 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() 来更改实体。在完成对数据库的所有结构更改后,在单独的脚本中处理实体。

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

最佳答案

您描述的场景完美地表明(通常)不可能在 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 中使用实体的这个问题,尤其是下面的引用:

don't use entities within migrations, you must not rely on the entity (PHP) code, but on the database only!

关于php - 学说迁移 : How to avoid SQL errors in the postUp step?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35529309/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com