【BigQuery】SAFE_CAST でデータ欠損に気づけなかった話
一言まとめ
SAFE_CAST
と CAST
はケースに応じて使い分けよう。
問題の発端
それは、いつものようにデータ基盤(BigQuery)の開発を進めていたある日のこと。
「このテーブルの○月×日以降のデータが入って無さそうなので確認してほしい」
この利用者からの連絡を受けてソワソワしながら確認したところ、
以下のテーブルのような状況になっていました。
dt | aaa | bbb |
---|---|---|
2023-07-10 | xxxx1 | yyyy1 |
2023-07-11 | xxxx2 | yyyy2 |
2023-07-12 | xxxx3 | yyyy3 |
2023-07-13 | NULL | yyyy4 |
2023-07-14 | NULL | yyyy5 |
2023-07-15 | NULL | yyyy6 |
2023-07-13
以降の aaa
カラムのデータが NULL
になっている...
連絡がなければ、全然気づけなかった事象でした。
データの欠損に気づけなかった原因
データの欠損自体は起こりうるものとした時に、
「データの欠損に長期間気づけなかったこと」は大きな問題です。
この問題を調査したところ、原因が大きく二つありそうでした。
- 定期的なデータの品質テストを行っていなかった
- データ変換時にエラー出力がなかったため、気づけなかった
「1.」は今後取り組んでいく課題として設定しました。
一方で「2.」を掘り下げてみると、
データの変換時に SAFE_CAST
関数を利用したことが、欠損に気づけなかった原因だということが見えてきました。
(前提情報として)データ基盤のシステム構成
そもそも SAFE_CAST
関数をどの処理で利用していたのかを説明するために、
データ基盤のシステム構成の一部を簡単に紹介します(※)。
※簡略化した構成図になっています。詳細なシステム構成は別記事で紹介します。
運用するデータ基盤には、Google BigQuery を採用しています。
データのワークフローは以下の図のようになっていて、ELT の形でデータを処理しています。
T(Transform) の部分は dbt を利用して SQL で変換処理を行う形です。
上図の dbt でデータの型を変更する際に、SAFE_CAST
or CAST
関数を利用しています。
参考:CAST|BigQuery リファレンス
参考:SAFE_CAST|BigQuery リファレンス
CAST と SAFE_CAST の挙動の違い
BigQuery にはデータの型変換をする関数に SAFE_CAST
と CAST
関数が用意されています。
CAST
関数は、変換先に指定した型に変換できるデータでない場合、エラーを出力します。
一方で SAFE_CAST
関数は、変換先に指定した型に変換できるデータでない場合、NULL
として出力します。
今回のポイントは、SAFE_CAST
関数がエラーにならないという点です。
エラーにならない、つまり ELT の処理を止めないことによって、
意図しないデータが入った場合にすぐ気づけない状況になっていました。
SAFE_CAST と CAST の使い分け
ではエラー検知を考慮するなら全て CAST
にすれば良いのでは、、
と思うところですが、SAFE_CAST
も利用するメリットがあります。
そこでそれぞれの利用ケースをまとめてみました。
SAFE_CAST の利用ケース
- 指定した型に変換できないデータは全て
NULL
とする場合 - 別途テストなどでエラー検知する仕組みを用意している場合
特に「空文字 or 特定の型のデータのみを含む変換」の場合には、
SAFE_CAST
だと SAFE_CAST({column_name} AS INT64)
で OK ですが、
CAST
だと CAST(IF({column_name} = '', NULL, {column_name}) AS INT64)
のように
IF
文を挟む必要が出てくるので、SAFE_CAST
の方がシンプルです。(※)
※ CAST('' AS INT64)
を実行すると Bad int64 value:
のエラーになります。
CAST の利用ケース
- 指定した型に変換できないデータはエラーとする場合
- 別途テストなどでエラー検知する仕組みを用意していない場合
意図しないデータの混入をいち早く検知するのであれば、
CAST
で型変換するようにしておく方が無難かな、という所感です。
今回のケースは CAST
を利用するようにし、意図しない型のデータが入る場合はエラーになるように変更しました。
まとめ
SAFE_CAST
でデータの欠損に気づけなかった問題の経緯と CAST
との使い分け案をまとめてみました。
データの型変換処理を実装する際に気を付けるポイントとして、参考になれば幸いです。
データの欠損、一緒に防いでいきましょう!
Discussion