Подтвердить что ты не робот

Создать Symfony2 светильники из БД?

Можно ли создавать светильники из существующей БД в Symfony2/Doctrine? Как я могу это сделать?

Пример:

Я определил 15 объектов, и мое приложение symfony2 работает. Теперь некоторые люди могут перейти к приложению, и, используя его, он ввел до 5000 строк до сих пор. Теперь я хочу, чтобы материал был вставлен в качестве светильников, но я не хочу этого делать вручную. Как я могу сгенерировать их из БД?

4b9b3361

Ответ 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 вы можете увидеть в последнем примере, как получить контейнер службы в вашей организации.

В этом контейнере службы вы можете получить службу доктрины, а затем менеджер сущностей. С менеджером сущностей вы сможете получить все данные из своей базы данных, которые вам нужны.

Надеюсь, это поможет вам!