dbtのnot_nullテストはオプションによって実行されるSQLが異なる

dbtを使っていなら、not_nullテストは何度も書くことになると思う。このテストを書いていて「手元では通るが、CIでは通らない」という一見謎現象に思えることにブチ当たったのでメモ。

起きた現象

手元からnot_nullテストを書いた。コンパイル済みのSQLは以下のようなものになる。

SELECT column
FROM model
WHERE column IS NULL

このテストをコミットしてCIで動かしていたところ、CIが落ちた。落ちた原因を調べていると、落ちたクエリは以下のものになっていることが分かった。

SELECT *
FROM model
WHERE column IS NULL

落ちている原因としてはテスト対象のテーブルにBigQueryの列レベルセキュリティがかかっていて、CIを実行しているサービスアカウントがその列にアクセスできないから、というものであったが、そもそも「なんでSELECT *になっているんだ?」というのが謎だった。

原因

調べてみたところ、CI環境では--store-failuresオプションが有効になっていたため、実行されるクエリがローカルとCIでは異なるということが起きていたようだ。

--store-failuresオプションはテストでどういう行が落ちたかを表示できるようにするためのオプションのようで、なるほどそれならSELECT *が走るなぁという感じ。以上、はまったのでメモでした。