我假设您想使用固定装置(而不仅仅是在开发数据库中转储生产或暂存数据库),因为 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(在这个包中,我将放置代码以加载固定装置)。如果第二个数据库不在您的开发机器上,您可以将 SQL 从另一台机器转储到开发机器。这应该是可能的,因为我们谈论的是 500 行而不是数百万行。
接下来你可以实现一个夹具加载器,它使用服务容器来检索第二个实体管理器,并使用 Doctrine 从第二个数据库中查询数据并将其保存到你的开发数据库(default 实体管理器):
<?php
namespace Acme\DemoBundle\DataFixtures\ORM;
use Doctrine\Common\DataFixtures\FixtureInterface;
use Doctrine\Common\Persistence\ObjectManager;
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Acme\DemoBundle\Entity\City;
use Acme\DemoBundle\Entity\Country;
class LoadData implements FixtureInterface, ContainerAwareInterface
{
private $container;
private $stagingManager;
public function setContainer(ContainerInterface $container = null)
{
$this->container = $container;
$this->stagingManager = $this->container->get('doctrine')->getManager('staging');
}
public function load(ObjectManager $manager)
{
$this->loadCountry($manager, 'Austria');
$this->loadCountry($manager, 'Germany');
$this->loadCountry($manager, 'France');
$this->loadCountry($manager, 'Spain');
$this->loadCountry($manager, 'Great Britain');
$manager->flush();
}
protected function loadCountry(ObjectManager $manager, $countryName)
{
$country = new Country($countryName);
$cities = $this->stagingManager->createQueryBuilder()
->select('c')
->from('AcmeDemoBundle:City', 'c')
->leftJoin('c.country', 'co')
->where('co.name = :country')
->setParameter('country', $countryName)
->getQuery()
->getResult();
foreach ($cities as $city) {
$city->setCountry($country);
$manager->persist($city);
}
$manager->persist($country);
}
}
我在loadCountry 方法中所做的是从staging 实体管理器加载对象,添加对夹具国家/地区的引用(当前夹具中已经存在的那个)并使用@ 持久化它987654330@ entity manager(你的开发数据库)。
来源: