BigQueryにASSERT文が来たのでDebuggingのおさらい


BigQueryにASSERT文が来た

2020-07-13 UTC以降、ASSERT文がサポートされました。
検証結果がTRUEであることを検証できます。

ERROR関数に次いで、2番目のDebugging系の機能です。
2020-07-14 10:36 JST現在、US以外のロケーションではサポートされていないようです。

Debuggingのおさらい

BigQueryには、従来ERROR関数があり、ないべき値はERROR関数で記述することができました。
新たにリリースされたASSERT文は、文であり、あるべき値をASSERT文で記述できるようになりました。

ASSERTの使い方

ASSERT文は、あるべき状態を検証します。プログラミングのASSERTのように、TRUEでない式が評価された場合にエラーを発生させます。ただし、デバッグレベルを調整して無視するような機能は今のところBigQueryにはないです。

文ですので、SELECT文と同じレベルで記述します。

エラーメッセージ付きASSERT

ASSERTの後に、BOOLを返す式を入れます。ASでエラー時のメッセージを記述します。
メッセージは文字列リテラルである必要があり、Scriptingから変数を入れることはできません(EXECUTE_IMMEDIATEを除く)。

ASSERT
  (
  SELECT
    LOGICAL_AND(x > 0)
  FROM
    UNNEST([1,-1]) AS x) AS 'x > 0'

エラーはこのように出ます。

x > 0

式がFALSENULLを返す場合エラーになります。

メッセージ省略ASSERT

メッセージは省略可能ですが、見返すことを考えると意味の分かるメッセージを入れておくことが推奨されます。

ASSERT 0 = 1

エラーはこのように出ます。

An internal error occurred and the request could not be completed. Error: 3144498

ASSERTの注意点

ASSERT文はキャッシュされません。同一の文を複数回実行したり、Scriptingで繰り返したりしても、毎回参照料金がかかります。

ERRORの使い方

ERROR関数は、あってはならない状態を検証します。
ERROR関数が評価されたタイミングでエラーを発生させます。

関数ですので、SELECT文の中で記述します。
IF関数やCASE式とセットで使ったり、存在しないことをSELECT ERRORで確認に使うことが多いです。

エラーメッセージ付きERROR

SELECT
  *
FROM
  UNNEST([-1])x
WHERE
IF
  (x > 0,
    TRUE,
    ERROR(FORMAT('Error: x must be positive but is %t', x)));

エラーはこのように出ます。

Error: x must be positive but is -1

エラーメッセージ省略ERROR

引数は省略できませんが、空文字列を入れることができます。

SELECT
  ERROR('')
An internal error occurred and the request could not be completed. Error: 3144498

NULLを入れると別なエラーになります。

SELECT
  ERROR(NULL)
Input to ERROR function must not be NULL

ASSERTとERRORの違いまとめ

  • ASSERTはあるべき状態を、ERRORはないべき状態を記述する
  • ASSERTは文、ERRORは関数
  • ASSERTは引数がFALSEかNULLだとエラー、ERRORは評価されると、エラー
  • ASSERTは文字列リテラル(実行前評価)、ERRORは文字列(実行時評価)をエラーメッセージにする
  • ASSERTはキャッシュされない、ERRORはキャッシュされる

使い所

ASSERT

データの全体感のチェックに使うと良さそうです。Scriptingでプロシージャにして、データの定期健康診断にしても良いですね。

  • UNIQUE制約を満たしているか
  • 外部キー制約を満たす割合は妥当か
  • 中央値平均値、パーセンタイルは妥当か
  • TrainingデータとServingデータに乖離がないか
  • データがテストデータと完全一致しているか(ユニットテスト)

ERROR

データの個別行のチェックに使うと良さそうです。EL(Extract/Load)やT(Transform)に混ぜ込んで、ワークフローの健康診断に使っても良いですね。

  • データに値域異常がないか
  • 外部キー制約を満たしているか
  • データの行内依存関係を壊す異常がないか(最大値列と最小値列が逆になっていないか)
  • 関数が想定の動作をしているか(ユニットテスト)

まとめ

BigQueryのDebugging機能にASSERT文が仲間入りして、データのあるべき状態を検証しやすくなりました。ワークフロー系ツールと相性が良さそうですので、通知系まで組み入れてデータの健康診断をちょくちょく出来ると良いですね。