We've built up a set of data fixtures to seed the database with all our reference values. We are also using the DoctrineMigrationsBundle to manage schema updates. We would like to trigger the fixture load within our initial schema migration class so the system gets populated before running any additional schema updates.
I found in the docs that you can make migration classes container aware, but I can't figure out how to jump from that to calling/running the data fixtures. I haven't found any good answers on Stackoverflow or via google. Has anyone done this and can point me in the right direction? (or have suggestions on a better way to manage seed data in conjunction with schema migrations). Thanks.
This is using Symfony Version: 2.4
This is interesting question. I've found the "dirty" solution, but it works well.
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));
}
}
This solution simply running console command php app/console doctrine:fixtures:load --fixtures=src/Acme/BlogBundle/DataFixtures/ORM --append
after "up" migration.
Sorry for poore English. If you'll find clear solution, share it ;)
I've made a migration class to address this very problem. The code is essentially inspired from the doctrine:fixtures:load command.
<?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;
}
}
Usage is pretty straightforward:
<?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
// [...]
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With