Doctrine orm 从DB生成Symfony2装置?

Doctrine orm 从DB生成Symfony2装置?,doctrine-orm,fixtures,symfony,Doctrine Orm,Fixtures,Symfony,是否可以从Symfony2/Doctrine中的现有数据库生成装置?我怎么能这么做 例如: 我已经定义了15个实体,我的symfony2应用程序正在运行。现在有些人可以浏览到应用程序,通过使用它,到目前为止,它已经插入了大约5000行。现在我想把这些东西作为固定装置插入,但我不想用手来做。如何从DB生成它们?在doctrine_fixture cookbook中,您可以在最后一个示例中看到如何在实体中获取服务容器 使用此服务容器,您可以检索条令服务,然后检索实体管理器。使用实体管理器,您将能够从

是否可以从Symfony2/Doctrine中的现有数据库生成装置?我怎么能这么做

例如:


我已经定义了15个实体,我的symfony2应用程序正在运行。现在有些人可以浏览到应用程序,通过使用它,到目前为止,它已经插入了大约5000行。现在我想把这些东西作为固定装置插入,但我不想用手来做。如何从DB生成它们?

在doctrine_fixture cookbook中,您可以在最后一个示例中看到如何在实体中获取服务容器

使用此服务容器,您可以检索条令服务,然后检索实体管理器。使用实体管理器,您将能够从数据库中获取所需的所有数据


希望这对你有帮助

这些装置非常有用,因为它们允许您创建对象并将其插入数据库。当您需要创建关联或使用其中一个密码编码器对密码进行编码时,这尤其有用。如果数据库中已经有数据,那么不需要将它们转换成PHP代码,只需要让PHP代码将相同的数据插入到数据库中即可。您可能只需执行SQL转储,然后以这种方式再次将它们重新插入数据库


如果您正在启动项目,但希望使用用户输入来创建项目,那么使用夹具将更有意义。如果配置文件中有默认用户,则可以读取该用户并插入该对象

在条令或Symfony2中没有直接的方式,但是为它编写代码生成器(在sf2内部或外部)将是微不足道的。只需拉动每个属性并生成一行代码来设置每个属性,然后将其放入fixture加载方法中。例如:

<?php
$i = 0;
$entities = $em->getRepository('MyApp:Entity')->findAll();
foreach($entities as $entity)
{
   $code .= "$entity_{$i} = new MyApp\Entity();\n";
   $code .= "$entity_{$i}->setMyProperty('" . addslashes($entity->getMyProperty()); . "'); \n");
   $code .= "$manager->persist($entity_{$i}); \n $manager->flush();";
   ++$i;
}
// store code somewhere with file_put_contents

根据我对您问题的理解,您有两个数据库:第一个数据库已经在生产中,填充了5000行,第二个数据库是您希望用于新测试和开发的新数据库。是这样吗

如果是,我建议您在测试环境中创建两个实体管理器:第一个是“默认”实体管理器,它将用于您的项目(您的控制器等)。第二个将用于连接到生产数据库。您将在这里找到如何处理多实体管理器:

然后,您应该创建一个Fixture类,该类可以访问您的容器。这里有一个“操作方法”:

使用容器,您将可以访问两个实体管理器。这就是“魔力”:您必须从生产数据库中检索对象,并将它们持久化到第二个实体管理器中,这将把它们插入测试数据库中

请注意两点:

  • 若对象之间存在关系,那个么您必须注意这些依赖关系:所有者端、反向端
  • 如果有5000行,请注意脚本将使用的内存。另一种解决方案可能是使用本机sql从生产数据库中检索所有行,并将它们插入测试数据库中。或者一个SQL脚本

我没有任何代码可以向您推荐,但我希望这个想法能对您有所帮助。

我假设您希望使用fixture(而不仅仅是将生产或暂存数据库转储到开发数据库中)因为a)如果更新代码,模式会更改,转储将不起作用;b)您不想转储孔数据库,只想扩展一些自定义装置。我能想到的一个例子是:您的登台数据库中有206个国家,用户向这些国家添加城市;为了保持装置较小,您的开发数据库中只有5个国家,但是您希望将用户添加到暂存数据库中这5个国家的城市添加到开发数据库中

我能想到的唯一解决方案是使用上面提到的DoctrineFixturesBundle和多个实体管理器

首先,您应该在
config.yml

doctrine:
    dbal:
        default_connection: default
        connections:
            default:
                driver:   %database_driver%
                host:     %database_host%
                port:     %database_port%
                dbname:   %database_name%
                user:     %database_user%
                password: %database_password%
                charset:  UTF8
            staging:
                ...

    orm:
        auto_generate_proxy_classes: %kernel.debug%
        default_entity_manager:   default
        entity_managers:
            default:
                connection:       default
                mappings:
                    AcmeDemoBundle: ~
            staging:
                connection:       staging
                mappings:
                    AcmeDemoBundle: ~
正如您所看到的,两个实体管理器都映射了AcmeDemoBundle(在这个bundle中,我将放置用于加载装置的代码)。如果第二个数据库不在您的开发机器上,您可以将SQL从另一台机器转储到开发机器上。这应该是可能的,因为我们谈论的是500行,而不是数百万行

接下来,您可以实现一个fixture加载器,它使用服务容器检索第二个实体管理器,并使用条令从第二个数据库查询数据并将其保存到您的开发数据库(默认的
实体管理器):

可以帮助您完成此操作。实际上,它允许加载带有YAML(或PHP数组)文件的装置

例如,您可以使用以下内容定义设备:

Nelmio\Entity\Group:
    group1:
        name: Admins
        owner: '@user1->id'
或者在PHP数组中使用相同的结构。这比生成可工作的PHP代码要简单得多

它还支持以下引用:

Nelmio\Entity\User:
    # ...

Nelmio\Entity\Group:
    group1:
        name: Admins
        owner: '@user1'
你可以用 它增加了使用如下命令为单个实体生成装置的能力

$ php bin/console doctrine:generate:fixture --entity=Blog:BlogPost --ids="12 534 124" --name="bug43" --order="1"
也可以创建完整快照

php app/console doctrine:generate:fixture --snapshot --overwrite

你说的“条令烹饪书”到底指的是什么?你有链接吗?我没能弄明白。。如果我有实体经理。。我还得自己写我的夹具文件。。。但我想要的更像是一个生成这些文件的任务。我说的是从现有数据库生成实体,你肯定要写自己的装置,我真的不明白你想做什么。我向您解释的是如何在功能中使用现有数据库。例如,您创建用户装置,并将其与数据库中已存储的城市相关联。是的,但这不是我想要的。我知道这些链接。我定义了实体,并使用我的应用程序在不同的表中插入了大约500行。
php app/console doctrine:generate:fixture --snapshot --overwrite