Как включить проверку внешних ключей с помощью функциональных тестов SQLite в Symfony 3.4 - PullRequest
0 голосов
/ 28 мая 2018

Я установил отношение один ко многим и ожидаю, что потомки будут удалены при удалении родителя.

Я забыл это сделать, и это создало ошибку в работе с MySQL, когда этоотказался удалить родителя из-за существования детей.

Я хотел написать функциональный тест для этого, но в SQLite по умолчанию отключены проверки внешнего ключа.

Как я могу PRAGMA foreign_keys = ON в соединенииконтроллер использует?Я выполнил это на тестовой стороне (фикстуры), но это не то же самое соединение, поэтому проверки внешнего ключа все еще отключены, и удаление родителя с существующими потомками не завершается неудачей (это должно быть).

1 Ответ

0 голосов
/ 28 мая 2018

Переопределите функцию boot вашего комплекта и выполните там запрос:

public function boot() {
    parent::boot();

    $env = $this->container->getParameter('kernel.environment');
    if ($env !== "test") {
        return;
    }

    /** @var Connection $connection */
    $connection = $this->container->get('doctrine')->getConnection();

    // Get initial state -- should be disabled
    $statement = $connection->prepare("PRAGMA foreign_keys");
    $statement->execute();
    echo __FILE__ . "@" . __LINE__ . "\n";
    print_r($statement->fetchAll());

    // Actually enable the foreign key checks on this connection
    $connection->exec("PRAGMA foreign_keys = ON;");

    // See if it was enabled
    $statement = $connection->prepare("PRAGMA foreign_keys");
    $statement->execute();
    echo __FILE__ . "@" . __LINE__ . "\n";
    print_r($statement->fetchAll());
}

Это выдаст следующее:

./src/AppBundle/DependencyInjection/Compiler/DoctrineCompilerPass.php@23
Array
(
    [0] => Array
        (
            [foreign_keys] => 0
        )

)
./src/AppBundle/DependencyInjection/Compiler/DoctrineCompilerPass.php@30
Array
(
    [0] => Array
        (
            [foreign_keys] => 1
        )

)

Теперь, в зависимости от используемых вами приборов,вам может потребоваться отключить проверку внешнего ключа при очистке схемы базы данных:

public function setUp() {
    $manager = $this->getContainer()
        ->get('doctrine')
        ->getManager();
    if (!isset($metadata)) {
        $metadata = $manager->getMetadataFactory()
            ->getAllMetadata();
    }
    $schemaTool = new SchemaTool($manager);
    // Disable the foreign key checks before the database is wiped
    $manager->getConnection()->exec("PRAGMA foreign_keys = OFF");
    $schemaTool->dropDatabase();
    if (!empty($metadata)) {
        $schemaTool->createSchema($metadata);
    }
    // Re-enable the foreign key checks now that it is created
    $manager->getConnection()->exec("PRAGMA foreign_keys = ON");
    $this->postFixtureSetup();

    $this->referenceRepository = $this->loadFixtures(array(ZZZ::class))->getReferenceRepository();
    $this->loadFixtures(array(ZZZ::class));
    $this->client = $this->makeClient();
}
...