Doctrine迁移是否可用于生产应用程序?

时间:2012-03-30 16:06:20

标签: php zend-framework doctrine-orm rails-migrations

作为previously discussed,我们正在开发一个围绕Zend Framework的PHP应用程序,当我们进入开发阶段时,需要经常以跨数据库的方式升级它的数据库。

我们目前正在使用Rails迁移,虽然它们在Ruby中(而且Windows上的Ruby就是它的混乱),但我们很难将迁移分发给具有基于Windows的安装的客户。即使在Linux上,使用Ruby访问MS SQL和Oracle数据库也很痛苦。

我们希望用Doctrine替换Rails迁移,但他们觉得非常不成熟。没有太多文档,跟踪器中有一些错误会引发项目状态的红色标记,例如:

查看代码,这两个实际上删除原始表或列并重新创建它而不保留数据。这是一个彻底的交易破坏者,让我觉得没有人真正使用Doctrine Migrations。

此外,我在文档中读到迁移使用顺序编号(版本1,版本2等)使它们完全不适合分支开发,但DoctrineMigrationsBundle Symfony documentation使用执行的基于日期的版本有意义。

有没有人有这个工具的实际经验,或者知道它的发展状况?

3 个答案:

答案 0 :(得分:14)

我们更多地了解了Doctrine Migrations,并对其内部工作方式有所了解(并更新了OP中链接的错误)。

主要问题是,Doctrine在迁移方面有着根本不同的方法。它从您的数据库模式构建一个抽象模型,然后允许您修改该模型。这些修改对底层数据库没有影响,但是Doctrine使用它们来推断必须在数据库上进行的实际更改。

就像数据库的差异一样。这有一些非常讨厌的后果。例如,如果重命名DB上的列,则模型上的操作如下所示:

public function renameColumn($oldColumnName, $newColumnName)
{
    $column = $this->getColumn($oldColumnName);
    $this->dropColumn($oldColumnName);

    $column->_setName($newColumnName);
    return $this;
}

如果您使用此功能然后让Doctrine应用迁移,那么它将查看旧架构和新架构之间的差异(缺少列,添加列及其类型)并推断是否需要重命名现有列或删除旧列并创建一个新列。这意味着Doctrine认为重命名一个列实际上与删除它并再次创建它相同,因此它非常愚蠢。

  • 如果您重命名单个列并且不更改其他任何内容,它将在DBMS上发出“重命名”命令。
  • 如果重命名一个列并将其类型(例如,varchar(80)更改为varchar(100)),它将删除它并再次创建它。
  • 如果你重命名2列而不改变任何东西,它会惊慌失措并放下它们并重新创建它们(diff算法就是那么简陋)

我认为这是一种糟糕的数据库迁移方法,因为它无法可靠地运行。这样一个工具的重点是保持数据跨迁移,这不符合基本要求。

这就是说,无论如何我们正在使用它,因为没有更好的东西。我们在不可靠的操作中添加了故意的失败消息,以避免让开发人员陷入许多陷阱。

答案 1 :(得分:7)

说实话,Doctrine迁移比大多数产品更好;但是,它们有点不成熟,很难找到文档。话虽如此,如果保持在有限的范围内,它们的工作正常。

此外,使用任何迁移工具,您只需要小心,不要指望它提供魔法。

话虽这么说,但是没有一个跨平台的工具可以像liquibase一样充满功能。此外,我所知道的其他工具都没有包含数据库文档工具。

以下关于liquibase的讨论应该为您提供足够的信息来帮助您入门:

http://slidedecks.wilmoore.com/2012-confoo/painless-version-controlled-database-refactoring

答案 2 :(得分:2)

如果您正在查看Doctrine 2,那么它可能有点不成熟,特别是如果您只想使用迁移库。根据我作为独立库的经验,而不是Doctrine2 ORM的一部分,它不是一个可靠的产品。值得赞扬的是,它仍然是Alpha,作为一个完整的ORM的Doctrine是一个非常好的库(并且迁移作为其中的一部分非常好)。

我在许多生产环境中使用Doctrine 1.X作为完整的ORM和迁移,它运行良好。