Я предполагаю, что вы хотите использовать фикстуры (а не просто сбросить производственную или промежуточную базу данных в базу данных разработки), потому что а) ваша схема изменится, и дампы не будут работать, если вы обновите свой код, или б) вы этого не сделаете хочу сбросить базу данных отверстий, но хочу только расширить некоторые пользовательские приборы. Пример, который я могу привести: у вас есть 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
, добавляю ссылку на страну прибора (ту, которая уже существует в ваших текущих приборах) и сохраняю ее, используя default
менеджер сущностей (ваша база данных разработки).
Источники: