在部署使用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:
一切都很好。
实际案例2:
这是行不通的。为什么?
Migration1的postUp()部分中的代码将与最新的应用程序代码一起运行。这意味着Doctrine ORM将期望col3已经存在于实体表中。但是,由于Migration2尚未运行到那时,因此没有字段col3。尝试在Migration1中保留新实体会导致SQL错误。
我提出了两个解决此问题的想法:
请评论您在该问题上的经验,并说明您如何处理。我敢肯定你们中的一些人在实践中遇到过这种情况。
您完美描述的场景表明,在一般情况下,无法在“教义迁移”中使用实体。
因此,恐怕要以一种健壮的方式进行这项工作的唯一方法是降到DBAL级别:
public function postUp(...) {
$this->connection->insert('entities', [
'col1' => 'value1',
'col2' => 'value2'
]);
}
通过使用DBAL查询,将直接提供要使用的列,而不是通过应用程序代码定义的实体(而不需要与当前表结构同步)间接提供。
另请参见“如何在Symfony中使用Doctrine迁移”一文的第4.2节,该节还描述了在Doctrine Migrations中使用实体时出现的问题,尤其是以下引号:
不要在迁移中使用实体,您一定不要依赖实体(PHP)代码,而只能依赖数据库!
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句