データ プロダクト モジュールの作成
独自のビジネス ロジックと分析モデルを定義するには、カスタム データ プロダクト モジュールを作成する必要があります。これにより、基盤テーブルに対して計算を実行し、デプロイ可能なデータセットにパッケージ化できます。
前提条件
カスタム データ プロダクト モジュールを作成する場合は、専用のカスタム Namespace を使用してパッケージ化することを強くおすすめします。また、使用する予定のソーステーブルがデータ基盤データセットに存在することを確認してください。
データ プロダクト モジュールの作成
データ プロダクト モジュールを定義するには、次の手順が必要です。
config/config.yamlファイル内でデータ プロダクト モジュールを登録します。これを行うには、data.modules.productsリストにエントリを追加します。
[...]
data:
[...]
# Configuration for data foundation and product modules.
modules:
# List of foundation modules.
foundation:
[...]
# List of data product modules.
product:
[...]
- moduleId: product_module_id
type: custom_namespace.flight_usd
dependsOn:
sapModule: erp
sapModuleCustNS: foundation_module_id
dataTargetId: product_target
enabled: true
tableSettings: "table_settings.yaml"
# Optional, references file in `config/custom_namespace_path/data_product/product_module_id/`
# If omitted, defaults to src/data_modules/custom_namespace_path/data_product/table_settings.default.yaml.
[...]
tableSettingsファイル(例:config/custom_namespace_path/data_product/product_module_id/table_settings.yaml)を作成します。この YAML は、マテリアライズや BigQuery の最適化の詳細など、テーブル構成を制御します。
common:
custom_sales_summary:
materialization_type: "table"
tags: ["custom", "sales", "reporting"]
partition_details:
column: "created_date"
partition_type: "date"
time_grain: "day"
cluster_details:
columns:
- "customer_id"
- アノテーション ファイルを作成します。
アノテーション ファイル <tablename>.yaml は、データ プロダクトの出力アーティファクト(テーブル、ビュー)ごとに作成され、列とフィールドを YAML 形式で記述します。コンパイル時に、ビルダーはプロダクトの annotations/ フォルダ(例: annotations/custom_sales_summary.yaml)内のアノテーションを自動的に検索し、これらの文字列を出力 Dataform スキーマ定義に直接マージして、BigQuery テーブル メタデータに保持します。
アノテーション config/custom_namespace_path/data_product/product_module_id/annotations/'tablename'.yaml ファイルの形式は次のとおりです。
description: "Description of the table or view purpose"
fields:
- name: "customer_id" # column name
description: "Customer identifier" # column description
- name: "column2"
description: "Description of Column 2"
- name: "column3"
description: "Description of Column 3"
- データ プロダクト フォルダ
config/custom_namespace_path/data_product/product_module_id/にmanifest.yamlファイルを作成し、タイプ、テーブル、モジュールの依存関係を維持します。マニフェスト ファイルの形式は次のとおりです。
type: sales_performance
builder: sap_product # Automatically resolves to the global SapProductBuilder fallback
dependencies:
sapModule:
type: sap
supportedVersions:
- ecc
- s4
データ プロダクト モジュールの例
フライトの例では、src/data_modules/custom_namespace_path/data_product/product_module_id/manifest.yaml を次の内容で作成します。
type: product_module_id
dependencies:
sapModule:
type: cortex.sap
supported_versions:
- ecc
- s4
tables:
common:
- tcurr
sapModuleCustNS:
type: custom_namespace .sap
supported_versions:
- ecc
- s4
tables:
common:
- sflight
builder: sap_product
- 次のステップでは、データ プロダクト テーブルの参照テーブル設定ファイルを拡張します。
使用する例では、次の内容で config/custom_namespace_path/data_product/product_module_id/table_settings.yaml を作成します。
ecc:
flights_usd:
materializationType: incremental
tags: [sap, dataproduct, masterdata]
s4:
flights_usd:
materializationType: incremental
tags: [sap, dataproduct, masterdata]
- データ プロダクト テーブルのアノテーションを作成して、ストレージ スキーマに説明を追加します。
使用する例では、次の内容で src/data_modules/custom_namespace_path/data_product/product_module_id/annotations/flights_usd.yaml ファイルを作成します。
description: "Flight scheduling and pricing information, including currency conversion to USD."
fields:
- name: "client_mandt"
description: "Client (Mandant), PK"
- name: "airline_code_carrid"
description: "Airline Carrier ID, PK"
- name: "flight_connection_number_connid"
description: "Flight Number, PK"
- name: "flight_date_fldate"
description: "Flight Date"
- name: "price_usd"
description: "Price in USD"
- name: "price"
description: "Price in local currency"
- name: "currency"
description: "Local currency"
- データ プロダクトのビジネス ロジックは、
jsファイルまたはsqlxファイルに保存されます。
次の例では、次の内容で src/data_modules/custom_namespace_path/data_product/product_module_id/definitions/flights_usd.js ファイルを作成します。
// ___MODULE_CONTEXT___
// ___TABLE_CONFIG___
const moduleConfig = config.product[moduleContext.moduleId];
const sapModuleConfigDatasetId = moduleConfig.sources.sapModule.datasetId;
const sapModuleCustNSConfigDatasetId = moduleConfig.sources.sapModuleCustNS.datasetId;
const materializationType = tableConfig.materializationType || "incremental";
const incremental = require("includes/cortex/incremental.js");
const publish_config = require("includes/cortex/publish_config.js");
const publishConfig = publish_config.getPublishConfig(
materializationType,
tableConfig,
moduleConfig,
[
"client_mandt",
"airline_code_carrid",
"flight_connection_number_connid",
"flight_date_fldate"
]
);
publish("flight_usd", publishConfig).query(
(ctx) => `
WITH flight_base AS (
SELECT
mandt,
carrid,
connid,
fldate,
price,
currency,
-- Convert flight date string (YYYYMMDD) to an integer to calculate SAP's inverted date key
CAST(99999999 - CAST(fldate AS INT64) AS STRING) AS inverted_fldate
FROM ${ctx.ref(sapModuleCustNSConfigDatasetId, 'sflight')} AS flight
),
ranked_exchange_rates AS (
SELECT
f.mandt,
f.carrid,
f.connid,
f.fldate,
f.price,
f.currency,
t.ukurs,
-- Window function to grab the closest historical exchange rate
ROW_NUMBER() OVER (
PARTITION BY f.mandt, f.carrid, f.connid, f.fldate
ORDER BY t.gdatu ASC
) AS latest_rate_rank
FROM flight_base f
LEFT JOIN ${ctx.ref(sapModuleConfigDatasetId, 'tcurr')} AS t
ON f.mandt = t.mandt
AND t.kurst = 'M' -- 'M' is the standard SAP default for average exchange rates
AND t.fcurr = f.currency
AND t.tcurr = 'USD'
-- Chronological (rate_date <= flight_date) translates to (t.gdatu >= inverted_fldate)
AND t.gdatu >= f.inverted_fldate
)
SELECT
client_mandt,
airline_code_carrid,
flight_connection_number_connid,
flight_date_fldate,
price,
currency,
price_usd,
CURRENT_TIMESTAMP() AS bq_loaded_at
FROM (
SELECT
mandt AS client_mandt,
carrid AS airline_code_carrid,
connid AS flight_connection_number_connid,
PARSE_TIMESTAMP('%Y%m%d', fldate) AS flight_date_fldate,
price AS price,
currency AS currency,
-- Currency Conversion Logic
CASE
WHEN currency = 'USD' THEN price
WHEN ukurs IS NULL THEN NULL -- Handles cases where no exchange rate is found
-- If UKURS is negative, it's an indirect quotation (1 USD = X Local) -> Divide
WHEN ukurs < 0 THEN ROUND(price / ABS(ukurs), 2)
-- If UKURS is positive, it's a direct quotation (1 Local = X USD) -> Multiply
ELSE ROUND(price * ukurs, 2)
END AS price_usd
FROM ranked_exchange_rates
WHERE latest_rate_rank = 1
)
${incremental.getWhere(ctx, ["flight_date_fldate"])}
`
);
カスタム Namespace 拡張機能の確認
Namespace、データ基盤、データ プロダクト モジュールを使用して Google Cloud Cortex Framework が正常に拡張されたことを確認する手順は次のとおりです。
データ プロダクト モジュールをデプロイするには、デプロイのページの説明に沿って
uv run targets build、deploy、build-and-deployを実行します。BigQuery コンソールで Dataform UI を開き、リポジトリとワークスペースに移動します。
Dataform UI で、コンソールにコンパイル エラーが表示されないことを確認します。
準備した拡張機能がパス
definitions/data_foundation/custom_namespace_path/とdefinitions/data_product/product_module_id/にデプロイされていることを確認します。Dataform パイプラインの実行手順に沿って操作します。
BigQuery で、プロダクト データセットにデータ プロダクト テーブルが含まれており、データが入力されていることを確認します。
- 前のステップ: データ基盤モジュールの作成
- 概要に戻る