When I run
console doctrine:fixtures:load --fixtures=src/App/PeopleBundle/DataFixtures/ORM
I don't want doctrine to purge every table that has an entity. Instead, I only want to purge tables for the fixtures that are in the explicitly specified directory.
However, it seems that, regardless of the target directory, symfony is finding every entity in every bundle, and purging every table associated with each entity.
How can I direct symfony2 to ignore all tables except for the specific tables for which I have written fixtures?
It's really not that hard to go about this the right way. First and foremost, yes, you use --append
, but you'll have a load of extra things added that you don't want. So you need to perform some basic checks in your fixtures to see if you actually need to add them (if they're already in the database, you don't).
The example I'm going to show you is a simple one: I have a locators
table containing the columns: id
and name
.
namespace Application\Model\Fixtures;
use Doctrine\Common\DataFixtures\OrderedFixtureInterface,
Doctrine\Common\DataFixtures\FixtureInterface,
Doctrine\Common\Persistence\ObjectManager,
Application\Model\Entity\Locator;
/**
* Class LoadLocators
*
* Pre-populates the locators table
*
* @package Application\Model\Fixtures
*/
class LoadLocators implements FixtureInterface, OrderedFixtureInterface
{
/**
* @var array The locators names that will be inserted in the database table
*/
protected $locators = ['id', 'xpath', 'css'];
/**
* {@inheritDoc}
*/
public function load(ObjectManager $manager)
{
foreach ($this->locators as $locatorName)
{
$locator = $this->findOrCreateLocator($locatorName, $manager);
/** Check if the object is managed (so already exists in the database) **/
if (!$manager->contains($locator))
{
$manager->persist($locator);
}
}
$manager->flush();
}
/**
* Helper method to return an already existing Locator from the database, else create and return a new one
*
* @param string $name
* @param ObjectManager $manager
*
* @return Locator
*/
protected function findOrCreateLocator($name, ObjectManager $manager)
{
return $manager->getRepository('Application\Model\Entity\Locator')->findOneBy(['name' => $name]) ?: new Locator($name);
}
/**
* {@inheritDoc}
*/
public function getOrder()
{
return 1;
}
}
The simple change here is that, if the object already exists in the database, find it and use that one instead. It really is that simple.
The command I now run has --append
at the end, but it doesn't append if the data already exists.
How do you think is Doctrine supposed to figured out what to purge and what not to? There is no information in a fixture telling which entities it will be loading. If you really need this, you'll have to do it manually.
First, you could use the --append
option to avoid purging the database. Second, the first thing you could do in your fixtures is to truncate the related tables.
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