데이터 제품 모듈 생성
자체 비즈니스 로직과 분석 모델을 정의하려면 맞춤 데이터 제품 모듈을 만들어야 합니다. 이렇게 하면 파운데이션 테이블에 대해 계산을 실행하고 배포 가능한 데이터 세트로 패키징할 수 있습니다.
기본 요건
맞춤 데이터 제품 모듈을 만들 때는 전용 맞춤 네임스페이스를 사용하여 패키징하는 것이 좋습니다. 또한 사용할 소스 테이블이 데이터 파운데이션 데이터 세트에 있는지 확인합니다.
데이터 제품 모듈 생성
데이터 제품 모듈 정의에는 다음 단계가 필요합니다.
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"])}
`
);
맞춤 네임스페이스 확장 프로그램 확인
네임스페이스, 데이터 파운데이션 또는 데이터 제품 모듈을 사용하여 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에서 제품 데이터 세트에 데이터 제품 테이블이 포함되어 있고 데이터가 채워져 있는지 확인합니다.
- 이전 단계: 데이터 기반 모듈 생성
- 개요로 돌아가기