Как загрузить фикстуры Symfony2 из класса миграции?

Мы создали набор фикстур данных, чтобы заполнить базу данных всеми нашими эталонными значениями. Мы также используем DoctrineMigrationsBundle для управления обновлениями схемы. Мы хотели бы инициировать загрузку фикстуры в нашем начальном классе миграции схемы, чтобы система заполнялась до запуска каких-либо дополнительных обновлений схемы.

Я нашел в документации, что вы можете настроить классы миграции с учетом контейнера., но я не могу понять, как перейти от этого к вызову/запуску фикстур данных. Я не нашел хороших ответов на Stackoverflow или через Google. Кто-нибудь сделал это и может указать мне правильное направление? (или у вас есть предложения по лучшему способу управления начальными данными в сочетании с миграцией схемы). Спасибо.

Это использует версию Symfony: 2.4


person Cameron M    schedule 18.07.2014    source источник


Ответы (2)


Это интересный вопрос. Я нашел "грязное" решение, но оно работает хорошо.


namespace Application\Migrations;

use Doctrine\DBAL\Migrations\AbstractMigration;
use Doctrine\DBAL\Schema\Schema;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\ContainerAwareInterface;

class Version20140811164659 extends AbstractMigration implements ContainerAwareInterface
{
    private $container;

    public function setContainer(ContainerInterface $container = null)
    {
        $this->container = $container;
    }

    public function up(Schema $schema)
    {
        // ... your code here
    }

    public function postUp(Schema $schema)
    {
        // here you have to define fixtures dir
        $this->loadFixtures('src/Acme/BlogBundle/DataFixtures/ORM');
    }

    public function down(Schema $schema)
    {
        // ... your code here
    }

    public function loadFixtures($dir, $append = true)
    {
        $kernel = $this->container->get('kernel');
        $application = new \Symfony\Bundle\FrameworkBundle\Console\Application($kernel);
        $application->setAutoExit(false);

        //Loading Fixtures
        $options = array('command' => 'doctrine:fixtures:load', "--fixtures" => $dir, "--append" => (boolean) $append);
        $application->run(new \Symfony\Component\Console\Input\ArrayInput($options));
    }
}

Это решение просто запускает консольную команду php app/console doctrine:fixtures:load --fixtures=src/Acme/BlogBundle/DataFixtures/ORM --append после миграции «вверх». Извините за плохой английский. Если вы найдете четкое решение, поделитесь им;)

person Serge Kvashnin    schedule 11.08.2014

Я сделал класс миграции для решения этой самой проблемы. Код по существу вдохновлен командой доктрины:фикстуры:загрузить.

<?php

namespace AppBundle\Migrations;

use Doctrine\Common\DataFixtures\Executor\ORMExecutor;
use Doctrine\Common\DataFixtures\FixtureInterface;
use Doctrine\Common\DataFixtures\Purger\ORMPurger;
use Doctrine\DBAL\Migrations\AbstractMigration;
use Symfony\Bridge\Doctrine\DataFixtures\ContainerAwareLoader;
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;

abstract class AbstractFixturesAwareMigration extends AbstractMigration implements ContainerAwareInterface
{
    private $container;
    private $fixtures;

    public function setContainer(ContainerInterface $container = null)
    {
        $this->container = $container;
    }

    protected function getContainer()
    {
        return $this->container;
    }

    protected function addFixture(FixtureInterface $fixture)
    {
        if(null === $this->fixtures) {
            $this->fixtures = new ContainerAwareLoader($this->getContainer());
        }

        $this->fixtures->addFixture($fixture);

        return $this;
    }

    protected function executeFixtures($em = null, $append = true, $purgeMode = ORMPurger::PURGE_MODE_DELETE)
    {
        $em = $this->getContainer()->get('doctrine')->getManager($em);
        $purger = new ORMPurger($em);
        $purger->setPurgeMode($purgeMode);
        $executor = new ORMExecutor($em, $purger);
        $executor->execute($this->fixtures->getFixtures(), $append);
        $this->fixtures = null;

        return $this;
    }
}

Использование довольно простое:

<?php

namespace Application\Migrations;

use AppBundle\Migrations\AbstractFixturesAwareMigration
use Doctrine\DBAL\Schema\Schema;
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Auto-generated Migration: Please modify to your needs!
 */
class Version20170726102103 extends AbstractFixturesAwareMigration
{        
    /**
     * @param Schema $schema
     */
    public function up(Schema $schema)
    {
        // this up() migration is auto-generated, please modify it to your needs
        // [...]
    }

    public function postUp(Schema $schema)
    {
        // LoadMyData can be any fixture class
        $this->addFixture(new LoadMyData());
        $this->executeFixtures();
    }        

    /**
     * @param Schema $schema
     */
    public function down(Schema $schema)
    {
        // this down() migration is auto-generated, please modify it to your needs
        // [...]
    }
}
person Lulhum    schedule 30.10.2017