docker run コマンドで MySQL のコンテナを立ち上げたら Table doesn't exist.
Docker の MySQL ではイメージを作るとき、/docker-entrypoint-initdb.d
というディレクトリにテーブル作成する.sql
ファイルをコピーしておくようにすると、コンテナを立ち上げたときに自動的に.sql
ファイルを実行してくれるという便利な機能があります。
参考: MySQLのDockerイメージの公式サイト
私もその便利な機能にあやかりお手軽にサンプルのデータベースを構築しようとしたのですがそのときにタイトルのような問題が発生したので備忘録として残します。
結論: SQL ファイルを順番に実行したかったらファイル名で順番付けするとよさそう
Files will be executed in alphabetical order.
(ファイルはアルファベット順に実行されます。)
参考: MySQLのDockerイメージの公式サイトの Initializing a fresh instance
という項目
ということで view を作りたい!でも view 作成用の SQL ファイルの中で参照してるテーブルの作成用の SQL ファイルは順番的に後になってしまうぞどうしよう、という場合はファイル名の先頭に00_
など順番付けできるようなプレフィックスをつけるようにすると良さそうです。
なにをしようとしたときに起こったか
ここでは私がこの問題にぶち当たるまでの経緯を説明しようと思います。
まずはテーブルを作成しよう
例えば以下のように好きなもののテーブルがあったとします。
docker_ddl/
├ cakes.sql
├ chocolates.sql
├ cookies.sql
└ pancakes.sql
view があったら便利そうだ、そうに違いない、よし作ろう
そしてそれらを一覧で見れたら便利かもねーということで my_favorites_view.sql
のような view を作成したとします。
docker_ddl/
├ cakes.sql
├ chocolates.sql
├ cookies.sql
├ my_favorites_view.sql
└ pancakes.sql
このとき my_favorites_view.sql
では中で pancakes.sql
を参照しているとします。(いい感じのが思いつかなかったので中身は省略します。。)
いでよ docker、パパーっとデータベースを立ち上げておくれ
この SQL ファイルたちを使うべく Dockerfile を書いてイメージを作ってdocker run
を実行します。
するとどうでしょうTable [データベース名].pancakes doesn't exist
となってしまいました。
なぜなのか
これはmy_favorites_view.sql
の実行時にはまだpancakes.sql
が実行されておらず存在しなかったためです。
ですが確かになんとなく言われてみれば上から順番に実行されそうなので「何でやねんっ!」とはなりませんでした。
どうすればいいか
ここで MySQL のイメージの公式を見るとアルファベット順で実行されますと書かれています。
それ以外で特に順番についての言及はないので結論にも書いたようになにか順番付けできるプレフィックスを決めるのがよさそうですね。
余談1
コンテナ生成するとき-d
オプションをつけた場合はバックグラウンドで実行されるのでコンテナ氏はスッといなくなってしまいます。
そんな場合はdocker logs [コンテナ名、またはコンテナ ID]
とするとログが見れるので原因追求しやすくなります。
余談2
やっぱり公式読むのは大事ですね、、、
英語ちゃんと読めるようになりたいですね、、、