DATABASE_URL環境変数に付加するserverVersionとは何なのか、省略するとどんな影響があるのか
Symfony Advent Calendar 2024 の2日目の記事です!🎄✨
Twitter (X) でもちょいちょいSymfonyネタを呟いてます。よろしければ フォロー お願いします🤲
昨日は @ippey_s さんの Symfonyのアトリビュートを使って、依存をいろいろ注入しまくる でした✨
何の話?
Symfonyアプリケーションに doctrine/doctrine-bundle
をインストールすると、Flexレシピ(参考)によって .env
に以下のような設定値の雛形が自動で挿入されます。
# DATABASE_URL="sqlite:///%kernel.project_dir%/var/data.db"
# DATABASE_URL="mysql://app:!ChangeMe!@127.0.0.1:3306/app?serverVersion=8.0.32&charset=utf8mb4"
# DATABASE_URL="mysql://app:!ChangeMe!@127.0.0.1:3306/app?serverVersion=10.11.2-MariaDB&charset=utf8mb4"
DATABASE_URL="postgresql://app:!ChangeMe!@127.0.0.1:5432/app?serverVersion=16&charset=utf8"
これらの設定値には ?serverVersion=xxx
というパラメータが付加されていますが、これが何なのか、省略するとどんな影響があるのか、というお話です。
何なのか
Doctrine DBALは、接続先のDBを抽象化するために Platform
というクラス を使用します。
Platform
クラスは、DBのベンダー およびバージョン に応じて異なる実装が用意されており、実際に接続するDBに合致するものを使用する必要があります。
そのため、どの Platform
を使用するかを決定するために、接続先のDBのバージョン番号の情報が必要となります。
serverVersion
は、Doctrine DBALにそれを教えるためのパラメータです。
省略するとどんな影響があるのか
結論としては、
- 一般的な構成のSymfonyアプリケーションでは、ほとんどの場合設定しなくても実害は特にない
- ただし、設定しておくことによる弊害も特にないので、できるだけ設定しておくのが無難
という認識でよさそうです。
以下、詳細です。
まず、serverVersion
パラメータについてはDoctrine DBALの公式ドキュメントの以下の箇所に解説があります。
これによると、serverVersion
が指定されていない場合、Doctrine DBALは実際にDBに接続し、例えばMySQLの場合なら SELECT VERSION();
をクエリしてバージョン番号を取得する、といった処理を自動で行ってくれます。
serverVersion
が指定されていれば、上記の処理は行われず、指定されているバージョン番号を信じて、対応する Platform
クラスが使用されます。
設定する/しないによる差はこれだけなので、ほとんどの状況において省略して問題になるケースは稀だと思います。
上記の公式ドキュメントの この部分 には「バージョンの自動検出が行われる場合、通常よりも早期にDB接続が確立される可能性がある」という注意書きのような記述がありますが、それが何か実害に繋がるという言及はなく、経験的にも見聞きしたことはありません。何か懸念すべき事項をご存知の方はコメントいただけると嬉しいです🙏
ただし、以下のスレッドに書かれている内容は考慮に値します。
このstof氏のコメントでは、以下の内容が指摘されています。
- キャッシュの事前生成(
bin/console cache:warmup
)を行うためには、使用するPlatform
クラスが決定されている必要がある- 例えば、doctrine/ormのマッピングを確定するにあたり、一部のマッピング設定で
Platform
に依存する処理が実行される
- 例えば、doctrine/ormのマッピングを確定するにあたり、一部のマッピング設定で
- そのため、
cache:warmup
を実行できるためには、以下のいずれかの条件を満たしている必要がある-
serverVersion
が指定されている -
cache:warmup
コマンドのプロセスがDATABASE_URL
環境変数を読み取ることができ、cache:warmup
コマンドのプロセスを実行しているサーバーからそのDBに接続する権限がある
-
- 2の条件の後半部分が満たされず
cache:warmup
が実行できないケースがよくある - 例えば、Dockerベースの環境で、Dockerfile内で
cache:warmup
を実行しようとしている場合、この時点でDBサーバーのコンテナがまだ存在していないので、DBに接続できずcache:warmup
が実行できない
これはなるほど確かにという内容です。
まとめ
-
DATABASE_URL
環境変数のserverVersion
パラメータは、Doctrine DBALにDBのバージョン番号を教えるためのもの - 省略された場合は実際にDBにバージョン番号をクエリする処理が自動で実行されるので、省略したからといってDoctrineが動作できなくなるというものではない
- ただし、Dockerfile内で
cache:warmup
を使用する構成などでは「DBにバージョン番号をクエリする処理」が実行できないせいでcache:warmup
が失敗するといった問題が起こり得るなど、影響はゼロではない - とりあえず設定しておくのが無難
以上です。
Symfony Advent Calendar 2024、明日は空きです🥺どなたかぜひご参加ください!
Discussion