【问题标题】:How to delete all data without breaking referential integrity using Doctrine?如何使用 Doctrine 在不破坏参照完整性的情况下删除所有数据?
【发布时间】:2011-08-14 13:06:22
【问题描述】:

我整理了一个unit testing plugin for Symfony 1.4,它尝试自动管理数据库,类似于 Django 的测试框架的做法(在测试之间销毁和重建数据库)。

在第一次测试运行之前销毁和重建数据库是有意义的,因为架构可能在开发过程中发生了变化,而且让开发人员手动保持他的测试数据库与他的模型同步简直是可怕的虐待狂.

但是,在第一次测试运行后,我发现删除所有数据通常会更快,这将是一个相当简单的任务,除了外键问题,需要删除数据正确的顺序。

对于 MySQL,这不是问题;只需SET FOREIGN_KEY_CHECKS = 0,你就可以破坏对你内心内容的引用完整性(当然,直到SET FOREIGN_KEY_CHECKS = 1,但在这种情况下,将没有数据留下,所以MySQL没有什么可抱怨的)。

但这只有在测试数据库使用 MySQL 时才有效。对于任何其他 DBMS(尤其是 Sqlite),这将失败。

Doctrine 1.2 是否提供了删除每个表中所有数据的方法,或者是否有“遵循”关系的方法(即确定哪些表具有外键并首先从中删除)?

【问题讨论】:

    标签: php doctrine foreign-keys doctrine-1.2


    【解决方案1】:

    我会使用 Doctrine DBAL 并首先找到外键。查看 Doctrine 关于Schema-Manager、其相关API documentation 以及ForeignKeyConstraint 中提供的方法的DBAL 文档。

    编辑:对于原则 1.2,似乎有一种类似的方法可以检索记录在 here 的外键。

    找到所有外键约束,并根据约束让代码决定删除数据的顺序。

    【讨论】:

    • 感谢您的建议。这看起来很棒,除了插件是为 Symfony 1.4 设计的,这意味着 Doctrine 1.2,而不是 2.0。是否有与之前版本的 Doctrine 兼容的方法?
    • 我认为您可以单独使用 DBAL 2.0 组件,但正如我刚刚读到的,似乎教义 1.2 内部有 dbal 组件(顺便说一句,它具有相同的功能)。
    • 不幸的是,Doctrine_Import->listTableConstraints() 似乎没有将外键视为约束;我在几个表上对其进行了测试,它正确地报告了唯一键约束,但没有报告外键。
    • 我又查看了一次文档,似乎正确的调用方法应该是listTableRelations()。也修正了我的答案,我的错。
    【解决方案2】:

    Doctrine_Data->purge() 利用Doctrine_Connection_UnitOfWork->buildFlushTree() 完成我想要完成的工作。

    有点道理,看看Doctrine_Data_Import->doImport()(即symfony doctrine:data-load)已经提供了我试图重新发明的功能......我怎么会错过那个? :P

    【讨论】:

    • 事实证明,即使这种方法也不是万无一失的。我最终为 MySQL 创建了一个自定义适配器,在每次清除操作之前禁用外键检查。
    【解决方案3】:

    另一种(虽然不完全是微不足道的)方法是使用事务。

    在测试开始时启动事务,然后在测试完成后发出回滚。数据库将删除测试期间创建的所有数据。

    但是,必须注意确保实际依赖事务的测试代码继续工作。

    这就是Django's test framework 的工作方式:

    class TestCase(TransactionTestCase):
        """
        Does basically the same as TransactionTestCase, but surrounds every test
        with a transaction, monkey-patches the real transaction management routines to
        do nothing, and rollsback the test transaction at the end of the test. You have
        to use TransactionTestCase, if you need transaction management inside a test.
        """
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-09
      • 1970-01-01
      相关资源
      最近更新 更多