こんにちは。SCSKの磯野です。
Dataformにはアサーションという機能があります。
また、Dataformでは増分テーブルを構成することができます。
そこで、アサーションにおいても増分ロジックでスキャンすることができないか、調査してみました。
やりたいこと
例えば下記のようなBigQueryのテーブルがあったとします。
ファイルを受信した時刻・ファイルのフォーマットチェック結果が格納されているテーブルです。
※本記事では以後、本テーブルをresult_table
とします
received_time
:ファイルを受信した時刻format_check_result
:ファイルのフォーマットが想定通りかをチェックした結果format_check_time
:ファイルのフォーマットチェックを行った時刻
前提/要件
- フォーマットチェックは毎日18:00に行われるため、
result_table
は毎日更新される。 - フォーマットチェックがFALSE(=異常なファイルを受信していた)の場合はアサーションエラーとするが、アサーションの実行対象はその日にチェックしたデータのみとしたい。
- 前日に届いたファイルが異常だった場合、前日はアサーションエラーとなるが、翌日はアサーションエラーとしたくない
※上記の例の場合、2025/7/1はアサーションエラーとなるが、2025/7/2,3はアサーションエラーとしたくない
- 前日に届いたファイルが異常だった場合、前日はアサーションエラーとなるが、翌日はアサーションエラーとしたくない
モチベーション
result_table
は、スキャン量を考慮して増分テーブルで構成されている。アサーションがフルスキャンとなってしまうと、result_table
を増分で構成した意味がなくなってしまう。- 一度異常なデータが格納されても、エラーは発砲され続けないでほしい。常に最新のデータのみのアサーションを実行してほしい。
課題:「type: “incremental”」の組み込みアサーションはフルスキャンとなる
実装方法・コード
まずは、result_table
を作成している処理の組み込みアサーションとして実装してみました。
テーブルのいずれかの行が false
の場合、アサーションは失敗します。
config { type: "incremental", name: "result_table", assertions: { rowConditions: [ 'format_check_result = TRUE' ] }, (略) } SELECT ...
結果
テーブルの作成は増分ロジックとなっていたのですが、組み込みアサーションについてはフルスキャンとなってしまいました。
対処法:手動アサーションを使用する
実装方法・コード
result_table
の作成処理とアサーションを分離し、手動アサーションとして実装してみました。
手動アサーション SQL クエリは行を返さないようにする必要があります。クエリの実行時にクエリが行を返すと、アサーションは失敗します。
config { type: "assertion", } SELECT * FROM ${ref("result_table")} WHERE format_check_result = FALSE -- チェック失敗(false)していたらアサーションエラーとする -- アサーションとresult_tableへのデータ格納はセットで実行する前提。 AND format_check_time >= DATETIME_SUB(CURRENT_DATETIME("Asia/Tokyo"), INTERVAL 5 MINUTE)
結果
下記工夫をすることで、アサーションを増分ロジックで構成することができました。
- 手動アサーションとする
- 直近5分間にresult_tableへINSERTされたデータのみをアサーションチェックすることで、増分ロジックを実現
まとめ
いかがだったでしょうか。
今回はDataformのアサーションにおいて、増分ロジックでスキャンする方法についてご紹介しました。
手動アサーションによる実装であれば、クエリの書き方次第で増分ロジックでアサーションを実装することができることがわかりました。
本記事が皆様のお役に立てれば幸いです。