このドキュメントでは、Dataform リポジトリに関する次の情報について説明します。
Dataform のリポジトリのベスト プラクティスの概要
このセクションでは、Dataform でリポジトリ サイズ、リポジトリ構造、コード ライフサイクルを管理するベスト プラクティスの概要を示します。
リポジトリ サイズのベスト プラクティス
リポジトリ サイズは、次のような Dataform における開発のさまざまな側面に影響します。
- コラボレーション
- コードベースの可読性
- 開発プロセス
- ワークフロー コンパイル
- ワークフローの実行
Dataform では、コンパイルのリソースに API の割り当てと制限を適用します。リポジトリ サイズが大きいと、リポジトリでこれらの割り当てと上限を超えることがあります。これにより、ワークフローのコンパイルと実行が失敗する可能性があります。
このリスクを軽減するために、大規模なリポジトリを分割することをおすすめします。大規模なリポジトリを分割する場合、大規模なワークフローを、各リポジトリに格納され、さらにリポジトリ間の依存関係で接続される多数の小規模なワークフローに分割します。
このアプローチにより、Dataform の割り当てと上限を遵守し、プロセスと権限を詳細に制御して、コードベースの読みやすさとコラボレーションを改善できます。ただし、分割リポジトリの管理は、単一のリポジトリの管理よりも困難になる場合があります。
Dataform でのリポジトリ サイズの影響について詳しくは、リポジトリ サイズの概要をご覧ください。リポジトリ分割のベスト プラクティスの詳細について、リポジトリの分割を確認する。
リポジトリ構造のベスト プラクティス
definitions ディレクトリ内のファイルは、ワークフローのステージを反映するように構成することをおすすめします。ニーズに最適なカスタム構造を採用できる点にもご留意ください。
推奨される次の definitions サブディレクトリの構造は、ほとんどのワークフローの主なステージを反映しています。
sources: データソース宣言を格納します。intermediate。データ変換ロジックを保存します。output: 出力テーブルの定義を格納します。extras(省略可)- 追加のファイルを格納します。
Dataform 内のすべてのファイル名は、BigQuery テーブルの命名ガイドラインに準拠している必要があります。Dataform リポジトリの definitions ディレクトリ内のファイル名は、サブディレクトリ構造を反映することをおすすめします。
リポジトリ内のファイルを構造化および命名するためのベスト プラクティスについて詳しくは、リポジトリ内のコードの構造化をご覧ください。
コード ライフサイクルのベスト プラクティス
Dataform のデフォルトのコード ライフサイクルは、次のフェーズで構成されています。
Dataform ワークスペースでのワークフロー コードの開発。
Dataform コアまたは JavaScript のみで開発できます。
ワークフロー設定ファイルの設定を使用して、コードをコンパイル結果にコンパイルします。
リリース構成とワークスペースのコンパイル オーバーライドを使用して、カスタム コンパイル結果を構成できます。
リリース構成を使用すると、リポジトリ全体のカスタム コンパイル結果を構成できます。後でワークフロー構成で実行をスケジュールできます。
ワークスペース コンパイル オーバーライドを使用すると、リポジトリ内のすべてのワークスペースに対してコンパイルのオーバーライドを構成し、各ワークスペースのカスタム コンパイル結果を作成できます。
BigQuery でのコンパイル結果の実行。
ワークフロー構成を使用して、実行またはリポジトリのコンパイル結果をスケジュールできます。
Dataform でコード ライフサイクルを管理するには、開発、ステージング、本番環境などの実行環境を作成します。
Dataform のコード ライフサイクルの詳細については、Dataform のコード ライフサイクルの概要をご覧ください。
実行環境を単一のリポジトリに保持するか、複数のリポジトリに保持するかを選択できます。
単一リポジトリ内の実行環境
ワークスペースのコンパイルのオーバーライドおよびリリース構成を使用して、分離された実行環境(開発、ステージング、本番環境など)を、1 つの Dataform リポジトリ内で作成できます。
分離された実行環境は次の方法で作成できます。
- スキーマごとに開発テーブルと本番環境テーブルを分割する。
- スキーマと Google Cloud プロジェクトごとに開発テーブルと本番環境テーブルを分割する。
- 開発、ステージング、本番環境のテーブルを Google Cloud プロジェクトごとに分割する。
その後、ワークフロー構成を使用して、ステージングと本番環境で実行をスケジュールできます。開発環境では、実行を手動でトリガーすることをおすすめします。
Dataform でワークフロー ライフサイクルを管理するためのベスト プラクティスの詳細については、ワークフロー ライフサイクルのベスト プラクティスをご覧ください。
複数のリポジトリのコード ライフサイクル
コード ライフサイクルの各ステージに合わせて Identity and Access Management の権限を調整するには、リポジトリの複数のコピーを作成して、それらを各 Google Cloud プロジェクトに保存します。
各 Google Cloud プロジェクトは、コード ライフサイクルのステージ(開発や本番環境など)に対応する実行環境として機能します。
このアプローチでは、すべてのプロジェクトでリポジトリのコードベースを同じにすることをおすすめします。リポジトリの各コピーでコンパイルと実行をカスタマイズするには、ワークスペースのコンパイルのオーバーライド、リリース構成、ワークフロー構成を使用します。
リポジトリ サイズの概要
このセクションでは、リポジトリ サイズがワークフロー開発と Dataform コンパイル リソースの使用量に与える影響と、リポジトリのコンパイル リソースの使用量を見積もる方法について説明します。
Dataform のリポジトリ サイズについて
リポジトリのサイズは、Dataform での開発の次の側面に影響します。
コラボレーション。大規模なリポジトリで複数の共同編集者が作業していると、pull リクエストが過剰に作成され、マージの競合のリスクが高まる可能性があります。
コードベースの読みやすさ。1 つのリポジトリでワークフローを構成するファイルの数が多いと、リポジトリ内を移動するのが難しくなることがあります。
開発プロセス。単一のリポジトリ内の大規模なワークフローの一部の領域では、ワークフローの残りの部分に適用される権限やプロセスとは異なる、カスタム権限やプロセス(スケジュール設定など)が必要になる場合があります。リポジトリ サイズが大きいと、ワークフローの特定の領域に合わせて開発プロセスを調整することが難しくなります。
ワークフローのコンパイル。Dataform ではコンパイル リソースに使用量上限が適用されます。リポジトリ サイズが大きいと、これらの上限を超えてコンパイルが失敗する可能性があります。
ワークフローの実行。実行中、Dataform はワークスペース内でリポジトリ コードを実行し、アセットを BigQuery にデプロイします。リポジトリが大きいほど、Dataform の実行に時間がかかります。
リポジトリのサイズが大きく、Dataform での開発に悪影響を及ぼしている場合は、リポジトリを複数の小さなリポジトリに分割できます。
リポジトリ コンパイルのリソースの上限について
開発中に、Dataform はワークスペース内のすべてのリポジトリ コードをコンパイルし、リポジトリ内のワークフローの表現を生成します。これはコンパイル結果と呼ばれます。Dataform ではコンパイル リソースに使用量上限が適用されます。
リポジトリが使用量上限を超える理由は次のとおりです。
- リポジトリ コードの無限ループバグ。
- リポジトリ コードのメモリリーク バグ。
- リポジトリ サイズが大きい(ワークフロー アクションの数が約 1, 000 個を超える)。
コンパイル リソースの使用量上限の詳細については、Dataform コンパイル リソースの上限をご覧ください。
リポジトリのコンパイル リソースの使用量を見積もる
リポジトリの次のコンパイル リソースの使用量を見積もることができます。
リポジトリのコンパイルの現在のコンパイル時間の使用状況を大まかに得るには、ローカルの Linux または macOS マシンで Dataform ワークフローのコンパイルの時間を計測します。
ワークフローのコンパイルの時間を計測するには、リポジトリ内で次の形式で Dataform CLI コマンド
dataform compileを実行します。time dataform compile次のコードサンプルは、
time dataform compileコマンドの実行結果を示しています。real 0m3.480s user 0m1.828s sys 0m0.260s
real の結果は経過時間の使用量の大まかな指標として、user の結果はリポジトリのコンパイルの CPU 時間の使用量の大まかな指標として扱うことができます。
リポジトリ内のアクションの生成されたグラフの合計サイズを大まかに把握するには、グラフの出力を JSON ファイルに書き込みます。非圧縮 JSON ファイルのサイズは、グラフの合計サイズのおおよその指標として扱うことができます。
ワークフローのコンパイル済みグラフの出力を JSON ファイルに書き込むには、リポジトリ内で次の Dataform CLI コマンドを実行します。
dataform compile --json > graph.json
リポジトリの分割
このセクションでは、Dataform リポジトリを分割し、リポジトリ間の依存関係を管理するための戦略について説明します。
リポジトリは Dataform のコアユニットです。リポジトリには、ワークフローを構成するすべての SQLX ファイルと JavaScript ファイル、Dataform 構成ファイルとパッケージが保存されます。ワークフローは、単一のリポジトリに保存することも、複数のリポジトリに分割することもできます。
Dataform でリポジトリを分割すると、次の利点があります。
- Dataform コンパイルのリソースの上限を遵守する。大規模なワークフローを複数の小さなリポジトリに分割すると、コンパイル リソースの Dataform の上限を超えるリスクが軽減されます。
- プロセスの細分化。継続的インテグレーション(CI)ルールなどのプロセスを、ワークフローの分割フラグメントとそれを開発するチームごとに個別に設定できます。
- 権限のきめ細かな設定。ワークフローの分割フラグメントと、それを開発するチームごとに個別に権限を設定して、ワークフロー全体のセキュリティを強化できます。
- ワークフローの分割された各フラグメントで作業するコラボレーターの数を最小限に抑えることで、コラボレーションを改善する。
- コードベースの可読性を向上させる。大規模なワークフローを構成するファイルを複数のリポジトリに分割すると、ワークフロー全体を一度に操作するよりも、各リポジトリを個別に操作する方が簡単になります。
- ワークフロー全体を実行する場合と比較して、ワークフローの各スプリット フラグメントの実行を高速化します。
Dataform でリポジトリを分割すると、次のようなデメリットがあります。
- 各 Dataform リポジトリおよび対応する Git リポジトリ用にカスタムの継続的インテグレーションと継続的開発(CI/CD)の構成が必要。
- 各 Dataform リポジトリおよび対応する Git リポジトリ用にカスタム スケジューリング構成が必要。
- 複数のリポジトリに格納されているワークフローのオブジェクト間の依存関係を管理するのが難しい。
- 複数のリポジトリに分割された SQL ワークフローの包括的な有向非巡回グラフ(DAG)の可視化が欠如している。各リポジトリで生成された DAG は、完全なワークフローの一部を表すだけに留まる。
リポジトリを分割するための戦略
リポジトリを分割すると、親 SQL ワークフローを構成するファイルが、個別の Dataform リポジトリに格納された小さな子ワークフローに分割されます。
リポジトリを分割する方法には、次のいずれかがあります。
- 開発チームごとに 1 つのリポジトリ。
- ドメインごとに 1 つのリポジトリ(例: 販売、マーケティング、ロジスティクス)。
- 1 つの中央リポジトリと、中央リポジトリのコンテンツをデータソースとして使用するドメインごとに 1 つのリポジトリ。
親ワークフローをサードパーティの Git ホスティング プラットフォームに格納するには、子ワークフローを含む個別のリポジトリを、専用のサードパーティ Git リポジトリに個別に接続する必要があります。
クロスリポジトリの依存関係の管理
リポジトリを分割する最も効率的な方法は、親 SQL ワークフローを自己完結型の子ワークフローに分割し、独立したリポジトリを作成することです。独立したリポジトリは、別のリポジトリのコンテンツをデータソースとして使用しません。この方法では、クロスリポジトリの依存関係を管理する必要はありません。
リポジトリ間の依存関係を回避できない場合は、リポジトリを連続したリポジトリに分割することで、依存関係を管理できます。この場合、リポジトリは前のリポジトリに依存し、次のリポジトリのデータソースになります。リポジトリとその依存関係の連続性は、親ワークフローの構造を最もよく反映している必要があります。
Dataform データソース宣言を使用して、リポジトリ間の依存関係を作成できます。編集中のリポジトリのデータソースとして、別の Dataform リポジトリの BigQuery テーブルタイプを宣言できます。データソースを宣言すると、他の Dataform ワークフロー アクションと同様に参照して、ワークフローの開発に使用できます。
クロスリポジトリ依存関係を持つリポジトリ間で分割されたワークフローの実行をスケジュールする場合は、クロスリポジトリ依存関係の順にリポジトリを 1 つずつ実行する必要があります。
リポジトリを双方向の依存関係を持つリポジトリのグループに分割することはおすすめしません。リポジトリ間の双方向の依存関係は、あるリポジトリが別のリポジトリのデータソースであり、かつそのリポジトリをデータソースとして使用している場合に発生します。リポジトリ間の双方向の依存関係により、親ワークフローのスケジューリングと実行、開発プロセスが複雑になります。
リポジトリ内のコードの構造化
このセクションでは、Dataform リポジトリのルート definitions ディレクトリでワークフロー ファイルを構造化して名前を付ける際のベスト プラクティスについて説明します。definitions ディレクトリの推奨構造は、ワークフローのステージを反映しています。ビジネスニーズに合った構造を採用できます。
definitions ディレクトリにワークフロー コードを構造化する理由は次のとおりです。
- ワークフローの一部にチームを割り当てることで、コードベースでのコラボレーションを改善する。
- 組織変更が発生した場合のワークフローの保守性を向上させる。
- コードベース内のナビゲーションを改善する。
- コードベースの拡張性を改善する。
- チームの管理オーバーヘッドを最小限に抑える。
definitions ディレクトリの推奨される構造
Dataform リポジトリのルート definitions ディレクトリには、ワークフローの要素を作成するコードが含まれています。definitions ディレクトリ内のファイルは、ワークフローの構造を反映したディレクトリ構造に整理できます。
ワークフローを開発するときに、ソーステーブルを宣言して変換し、ビジネスや分析の目的で使用できる出力テーブルを作成します。
ワークフローの 3 つの主要なステージを区別できます。
- データソースの宣言。
- ソースデータの変換。
- 変換されたソースデータからの出力テーブルの定義。
definitions ディレクトリ内のサブディレクトリの次の構造は、ワークフローの主要なステージを反映しています。
sources- データソースの宣言とソースデータの基本的な変換(フィルタリングなど)。
intermediatesourcesから読み取り、データを変換するテーブルとアクション。変換後のデータを使用してoutputsテーブルを定義します。通常、Dataform が BigQuery で実行した後に、ビジネス インテリジェンス(BI)ツールなどの追加のプロセスやツールに公開されないテーブル。outputs- Dataform が BigQuery で実行した後に、BI などのプロセスやツールで使用されるテーブルの定義。
extra- ワークフローのメイン パイプライン外のファイル。たとえば、機械学習などの追加用途に備えて準備されたワークフロー データを含むファイル。オプションのカスタム サブディレクトリ。
sources のベスト プラクティス
sources サブディレクトリには、ワークフローの最初のステージ(ソースデータの宣言と基本的な変換)が含まれています。
sources サブディレクトリに、列のフィルタ、分類、キャスト、名前変更を行うデータソース宣言とテーブルを保存します。
複数のソースのデータを結合したテーブルを保存しないようにします。
intermediate サブディレクトリに保存されているテーブルの sources データを変換します。
複数のプール(Google 広告や Google アナリティクスなど)からデータソースを宣言する場合は、プールごとにサブディレクトリを割り当てます。
次のサンプルは、2 つのソースプールを含む sources のサブディレクトリ構造を示しています。
definitions/
sources/
google_ads/
google_ads_filtered.sqlx
google_ads_criteria_metrics.sqlx
google_ads_criteria_metrics_filtered.sqlx
google_ads_labels.sqlx
google_ads_labels_filtered.sqlx
google_analytics/
google_analytics_users.sqlx
google_analytics_users_filtered.sqlx
google_analytics_sessions.sqlx
同じスキーマ内で複数のデータソース テーブルを宣言する場合は、宣言を 1 つの JavaScript ファイルに統合できます。
JavaScript を使用してデータソース宣言を作成する方法については、JavaScript のみを使用してワークフローを作成するをご覧ください。
次のコードサンプルは、1 つの JavaScript ファイルで宣言された、1 つのスキーマ内の複数のデータソースを示しています。
[
"source_table_1",
"source_table_2",
"source_table_3"
].forEach((name) =>
declare({
database: "gcp_project",
schema: "source_dataset",
name,
})
);
データソースの変更からワークフローを保護するには、データソース宣言ごとにビューを作成します(例: analytics_users_filtered.sqlx)。ビューには、ソースデータの基本的なフィルタリングとフォーマットを含めることができます。ビューを sources サブディレクトリに保存します。
次に、intermediate テーブルまたは outputs テーブルを作成するときに、未加工のソーステーブルではなくビューを参照します。この方法では、ソーステーブルをテストできます。ソーステーブルが変更された場合は、フィルタの追加やデータの再キャストなどにより、ビューを変更できます。
intermediate のベスト プラクティス
intermediate サブディレクトリには、ワークフローの第 2 段階である、1 つまたは複数のソースからのソースデータの変換と集計が含まれています。
intermediate サブディレクトリには、sources サブディレクトリ内の 1 つ以上のソースからソースデータを大幅に変換するファイル(データを結合するテーブルなど)を保存します。intermediate サブディレクトリ内のテーブルは、通常、ソーステーブルまたは他の intermediate テーブルからデータをクエリします。
intermediate テーブルを使用して outputs テーブルを作成します。通常、intermediate テーブルは、Dataform が BigQuery で実行した後に、追加の目的(データ分析など)で使用されることはありません。intermediate テーブルは、出力テーブルの作成を可能にするデータ変換ロジックと考えることができます。
すべての intermediate テーブルをドキュメント化してテストすることをおすすめします。
outputs のベスト プラクティス
outputs サブディレクトリには、ワークフローの最終ステージ(変換されたデータからビジネス目的の出力テーブルを作成する)が含まれています。
outputs ディレクトリには、Dataform が BigQuery に実行した後に、追加のプロセスまたはツール(レポートやダッシュボードなど)で使用する予定のテーブルを保存します。outputs ディレクトリのテーブルは、通常、intermediate テーブルからデータをクエリします。
outputs テーブルを、関連する事業体(マーケティング、注文、分析など)ごとにグループ化します。各事業体にサブディレクトリを割り当てます。
BigQuery に出力テーブルを個別に保存するには、出力テーブル専用のスキーマを構成します。テーブル スキーマを構成する手順については、テーブル設定をオーバーライドするをご覧ください。
次のサンプルは、sales と marketing の事業体を含む outputs のサブディレクトリ構造を示しています。
definitions/
outputs/
orders/
orders.sqlx
returns.sqlx
sales/
sales.sqlx
revenue.sqlx
marketing/
campaigns.sqlx
すべての outputs テーブルをドキュメント化してテストすることをおすすめします。
命名戦略
Dataform 内のすべてのファイル名は、BigQuery テーブルの命名ガイドラインに準拠している必要があります。
Dataform リポジトリの definitions ディレクトリ内のファイル名は、サブディレクトリ構造を反映することをおすすめします。
sources サブディレクトリのファイル名は、ファイルが関連付けられているソースを指している必要があります。ソースの名前をファイル名の接頭辞として追加します(例: analytics_filtered.sqlx)。
intermediate サブディレクトリでは、共同編集者が intermediate ファイルを明確に区別できるように、ファイル名でサブディレクトリを識別できるようにする必要があります。一意の接頭辞を選択し、intermediate ディレクトリ内のファイルにのみ適用します(例: stg_ads_concept.sqlx)。
outputs サブディレクトリのファイル名は、簡潔なものにする必要があります(例: orders.sqlx)。異なるエンティティ サブディレクトリに同じ名前の outputs テーブルがある場合は、エンティティを識別する接頭辞(sales_revenue.sqlx や ads_revenue.sqlx など)を追加します。
次の例は、推奨される命名戦略に準拠したファイル名を持つ definitions ディレクトリ内のサブディレクトリ構造を示しています。
definitions/
sources/
google_analytics.sqlx
google_analytics_filtered.sqlx
intermediate/
stg_analytics_concept.sqlx
outputs/
customers.sqlx
sales/
sales.sqlx
sales_revenue.sqlx
ads/
campaigns.sqlx
ads_revenue.sqlx
コンパイルとスケジューリングのベスト プラクティス
リポジトリのスケジュール実行とオーケストレーション ワークフローを構成する際は、次のベスト プラクティスに沿って、コンパイルの信頼性を確保してください。
- スケジュールされた本番環境の実行にリリース構成を使用する: リリース構成は、予測可能なスケジュールでリポジトリ コードをコンパイルし、結果のコンパイル結果を保存します。本番環境の実行パイプラインが実行されると、リモートの Git リポジトリにネットワーク リクエストを開始することなく、この保存された結果に対してすぐに実行されます。
- commitish のコンパイルを開発タスクと低頻度タスクに制限する: ブランチ、タグ、commit SHA などの Git commitish で
CreateCompilationResultを直接呼び出すと、Dataform は呼び出しごとにネットワーク経由でリポジトリのクローンを作成する必要があります。本番環境の cron ジョブやオーケストレーション DAG を、Git commitish から高頻度で繰り返しコンパイルするように構成しないでください。 - 自動再試行とスタッガー スケジュールを構成する: アーキテクチャで外部スケジューラの Git commitish からのコンパイルが必要な場合は、指数バックオフによる自動再試行を構成し、同時実行 cron タイマーをスタッガーします。詳細な再試行コードの例とトラブルシューティングの手順については、リモート リポジトリにアクセスできないをご覧ください。
次のステップ
- Dataform のコード ライフサイクルと構成方法の詳細について、Dataform のコード ライフサイクルの概要を確認する。
- ワークフロー ライフサイクルのベスト プラクティスの詳細については、ワークフロー ライフサイクルのベスト プラクティスをご覧ください。
- コンパイル リソースの上限の詳細については、Dataform コンパイル リソースの上限をご覧ください。
- Dataform リポジトリをサードパーティの Git リポジトリに接続する方法については、サードパーティの Git リポジトリに接続するをご覧ください。
- Dataform のワークフローの詳細については、ワークフローの概要をご覧ください。