如何从迁移类加载Symfony2 fixture?

时间:2014-07-18 15:49:22

标签: symfony doctrine-orm symfony-2.4 doctrine-migrations

我们已经建立了一组数据夹具,用我们所有的参考值为数据库设定种子。我们还使用DoctrineMigrationsBundle来管理架构更新。我们希望在初始模式迁移类中触发夹具加载,以便在运行任何其他模式更新之前填充系统。

我在文档中发现你可以migration classes container aware,但我无法弄清楚如何跳转到调用/运行数据夹具。我没有在Stackoverflow或谷歌上找到任何好的答案。有没有人这样做,可以指出我正确的方向? (或者有关于与模式迁移一起管理种子数据的更好方法的建议)。感谢。

这是使用Symfony版本:2.4

2 个答案:

答案 0 :(得分:6)

这是一个有趣的问题。我发现了“脏”的解决方案,但效果很好。


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。 抱歉poore英语。如果您找到明确的解决方案,请分享;)

答案 1 :(得分:2)

我已经完成了一个迁移课程来解决这个问题。代码基本上来自于教义:fixtures:load命令。

<?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
        // [...]
    }
}