【问题标题】:How to load Symfony2 fixtures from migration class?如何从迁移类加载 Symfony2 固定装置?
【发布时间】:2014-07-18 15:49:21
【问题描述】:

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

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

这是使用 Symfony 版本:2.4

【问题讨论】:

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


    【解决方案1】:

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

    
    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。 对不起英语不好。如果您能找到明确的解决方案,请分享;)

    【讨论】:

      【解决方案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
              // [...]
          }
      }
      

      【讨论】:

        猜你喜欢
        • 2012-11-29
        • 2011-04-29
        • 2012-10-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-03-24
        • 1970-01-01
        • 2011-09-13
        相关资源
        最近更新 更多