polidog lab

Top About Rss
2021年06月18日

SymfonyでSentryBundleを入れるとAliceBundleのPurgeに失敗する場合の対応方法

Symfony5.3 + hautelook/alice-bundleの組み合わせで RefreshDatabaseTrait を利用してテストを書いてたんですが、sentry-symfonyを導入してテストを実行したらエラーが大量に発生しました。

エラーを確認してみると以下のTRUNCATE TABLEできないとエラーが出てました。

PDOException: SQLSTATE[42000]: Syntax error or access violation: 1701 Cannot truncate a table referenced in a foreign key constraint ...

なぜエラーになったのか?

使っているDatabaseはMySQLときは、AliceBundle側でFixtureを挿入するときに SET FOREIGN_KEY_CHECKS = 0; を設定してくれるんですが、どうやらそれが実行されないことが原因のようでした。
どこで SET FOREIGN_KEY_CHECKS = 0; を実行しているかというと、theofidry/alice-data-fixturesのPurger::purge()の部分でした。

以下のコードで $disableFkChecksの値がsentry-symfonyを導入していると false になってしまい SET FOREIGN_KEY_CHECKS = 0;が設定できなかったということでした。

<?php
        // See the progress in https://github.com/doctrine/data-fixtures/pull/272
        $disableFkChecks = (
            $this->purger instanceof DoctrineOrmPurger
            && in_array($this->purgeMode->getValue(), [PurgeMode::createDeleteMode()->getValue(), PurgeMode::createTruncateMode()->getValue()])
            && $this->purger->getObjectManager()->getConnection()->getDriver() instanceof AbstractMySQLDriver
        );

https://github.com/theofidry/AliceDataFixtures/blob/bcfdf64bc940eb4a7b40b46d9ca5251e5692cc11/src/Bridge/Doctrine/Purger/Purger.php#L98-L102

なぜ $disableFkChecks が trueにならないのか?

調べてみたところ $this->purger->getObjectManager()->getConnection()->getDriver() ここで取得しているDBのDriverがAbstractMySQLDriverではなく、 Sentry\SentryBundle\Tracing\Doctrine\DBAL\TracingDriverが入っていたために、$disableFkChecksがfalseになっていました。

どう対処するべきか?

そもそもTestではSentryは必要ないので、tracingの設定をfalseにすることで対応しました。

config/packages/test/sentry.yaml

sentry:
    tracing: false

これでTRUNCATE TABLEが無事に実行でき、エラーがになりません。

comments powered by Disqus