Создать Symfony2 светильники из БД?
Можно ли создавать светильники из существующей БД в Symfony2/Doctrine? Как я могу это сделать?
Пример:
Я определил 15 объектов, и мое приложение symfony2 работает. Теперь некоторые люди могут перейти к приложению, и, используя его, он ввел до 5000 строк до сих пор. Теперь я хочу, чтобы материал был вставлен в качестве светильников, но я не хочу этого делать вручную. Как я могу сгенерировать их из БД?
Ответы
Ответ 1
В Доктрине или Symfony2 нет прямого способа, но писать генератор кода для него (внутри или снаружи sf2) будет тривиальным. Просто вытащите каждое свойство и создайте строку кода, чтобы установить каждое свойство, а затем поместите его в свой метод загрузки прибора. Пример:
<?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
Ответ 2
Насколько я понимаю ваш вопрос, у вас есть две базы данных: первая уже создана и заполнена 5000 строками, вторая - это новая база данных, которую вы хотите использовать для нового теста и разработки. Это правильно?
Если это так, я предлагаю вам создать в вашей тестовой среде два диспетчера сущностей: первый будет "по умолчанию", который будет использоваться в вашем проекте (ваши контроллеры и т.д.). Второй будет использоваться для подключения к вашей производственной базе данных. Вы найдете здесь, как иметь дело с несколькими менеджерами сущностей: http://symfony.com/doc/current/cookbook/doctrine/multiple_entity_managers.html
Затем вы должны создать класс Fixture, который будет иметь доступ к вашему контейнеру. Здесь есть "как": http://symfony.com/doc/current/bundles/DoctrineFixturesBundle/index.html#using-the-container-in-the-fixtures.
Используя контейнер, вы получите доступ к обоим менеджерам сущностей. И это "волшебство": вам нужно будет восстановить объект из вашей производственной базы данных и сохранить их во втором менеджере сущностей, который будет вставлять их в тестовую базу данных.
Я обращаю ваше внимание на две точки:
- Если есть связь между объектом, вам придется позаботиться об этих зависимостях: стороне владельца, обратной стороне,...
- Если у вас 5000 строк, позаботьтесь о памяти, которую будет использовать ваш script. Другим решением может быть использование native sql для извлечения всех строк из вашей производственной базы данных и их вставки в тестовую базу данных. Или SQL script...
У меня нет кода, который бы вам предлагал, но я надеюсь, что эта идея поможет вам.
Ответ 3
Я предполагаю, что вы хотите использовать приборы (а не просто выгружать производственную или промежуточную базу данных в базе данных разработки), потому что: а) изменения вашей схемы и дампы не будут работать, если вы обновите код или 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
, добавляю ссылку на страну крепления (ту, которая уже существует в ваших текущих светильниках), и сохраняйте ее с помощью default
менеджер объектов (ваша база данных разработки).
Источники:
Ответ 4
Инструменты Doctrine Fiestures полезны, поскольку они позволяют создавать объекты и вставлять их в базу данных. Это особенно полезно, когда вам нужно создавать ассоциации или сказать, закодировать пароль, используя один из кодов паролей. Если у вас уже есть данные в базе данных, вам не нужно будет выводить их из этого формата и превращать их в PHP-код, только чтобы этот PHP-код ввел те же данные обратно в базу данных. Вероятно, вы могли бы просто создать дамп SQL, а затем снова вставить их в свою базу данных.
Использование прибора будет иметь больше смысла, если вы инициируете свой проект, но хотите использовать пользовательский ввод для его создания. Если в вашем конфигурационном файле был пользователь по умолчанию, вы могли бы прочитать это и вставить объект.
Ответ 5
AliceBundle может помочь вам в этом. В самом деле, это позволяет загружать светильники с файлами YAML (или PHP).
Например, вы можете определить свои приборы с помощью:
Nelmio\Entity\Group:
group1:
name: Admins
owner: '@user1->id'
Или с той же структурой в массиве PHP. Это проще, чем генерировать рабочий PHP-код.
Он также поддерживает ссылки:
Nelmio\Entity\User:
# ...
Nelmio\Entity\Group:
group1:
name: Admins
owner: '@user1'
Ответ 6
вы можете использовать https://github.com/Webonaute/DoctrineFixturesGeneratorBundle
Это добавляет возможность генерировать светильники для единого объекта, используя команды типа
$ 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
Ответ 7
В куковой книге doctrine_fixture вы можете увидеть в последнем примере, как получить контейнер службы в вашей организации.
В этом контейнере службы вы можете получить службу доктрины, а затем менеджер сущностей. С менеджером сущностей вы сможете получить все данные из своей базы данных, которые вам нужны.
Надеюсь, это поможет вам!