Workaround for "1701 Cannot truncate a table referenced in a foreign key constraint" using doctrine:

I've been following a BDD approach using Behat to develop a RESTful API on my current project and wanted to fully isolate the data base from feature to feature, so first I tried with:php

/**
 * @BeforeFeature
 */
public static function beforeFeature(BeforeFeatureScope $scope)
{
    echo shell_exec('app/console doctrine:schema:drop --env=test --force');
    echo shell_exec('app/console doctrine:schema:create --env=test');
    echo shell_exec('app/console doctrine:fixtures:load --env=test -n');
}

and it was pretty slow, in my case it was taking an average of 1,5s...git

Reading the DoctrineFixturesBundle help I found a nice --purge-with-truncate flag, but TA DAN, it was failing with this issue: https://github.com/doctrine/data-fixtures/pull/127github

Well, I solved it by replacing the MySqlPlatform::getTruncateTableSQL method like:shell

config_test.yml

doctrine: dbal: driver_class: Your\OwnBundle\DBAL\Driver ...app

src/Your/OwnBundle/DBAL/Driver.php

<?phpthis

namespace Your\OwnBundle\DBAL;

use Doctrine\DBAL\Driver\PDOMySql\Driver as BaseDriver;

class Driver extends BaseDriver
{
    /**
     * {@inheritdoc}
     */
    public function getDatabasePlatform()
    {
        return new Platform();
    }
}

src/Your/OwnBundle/DBAL/Platform.php

<?phpspa

namespace Your\OwnBundle\DBAL;

use Doctrine\DBAL\Platforms\MySqlPlatform;

class Platform extends MySqlPlatform
{
    /**
     * {@inheritdoc}
     */
    public function getTruncateTableSQL($tableName, $cascade = false)
    {
        return sprintf('SET foreign_key_checks = 0;TRUNCATE %s;SET foreign_key_checks = 1;', $tableName);
    }
}

And finally:code

/**
 * @BeforeFeature
 */
public static function beforeFeature(BeforeFeatureScope $scope)
{
    echo shell_exec('app/console doctrine:fixtures:load --env=test --purge-with-truncate -n');
}

It's hacky, I know, but it does the job for the tests and cuts down the average time to 0,4s.orm

相關文章
相關標籤/搜索