4

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

我在文档中发现您可以让迁移类容器感知,但我不知道如何从那里跳转到调用/运行数据夹具。我在 Stackoverflow 或通过谷歌没有找到任何好的答案。有没有人这样做并且可以指出我正确的方向?(或者有关于结合模式迁移管理种子数据的更好方法的建议)。谢谢。

这是使用 Symfony 版本:2.4

4

2 回答 2

7

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


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在“向上”迁移后运行控制台命令。对不起英语不好。如果您能找到明确的解决方案,请分享;)

于 2014-08-11T15:37:35.993 回答
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
        // [...]
    }
}
于 2017-10-30T13:41:31.063 回答