Creación de módulos de productos de datos
Para definir tu propia lógica empresarial y modelos analíticos, crea un módulo de productos de datos personalizado. Esto te permite ejecutar cálculos en tus tablas de base o productos de datos ascendentes y empaquetar los resultados en conjuntos de datos implementables.
Requisitos previos
Te recomendamos crear módulos de productos de datos personalizados en un espacio de nombres personalizado dedicado para mejorar la administración del ciclo de vida. Además, asegúrate de que la tabla de origen que planeas usar exista en el conjunto de datos de la base de datos.
Creación de un módulo de productos de datos
La definición del módulo de productos de datos requiere los siguientes pasos:
- Registro del módulo de productos de datos en el archivo
config/config.yaml. Para ello, extiende la listadata.modules.productscon la entrada:
data:
# Configuration for data foundation and product modules.
modules:
# List of data product modules.
product:
# Recommended naming for product_module_id:
# custom_namespace_data_product_module_type
- moduleId: product_module_id
# Type of the data product (namespaced).
type: custom_namespace.data_product_module_type
# Map of module dependencies.
dependsOn:
sapModule: erp
sapModuleCustNS: foundation_module_id
# Reference to the target dataset ID.
dataTargetId: product_target
# Whether the module is enabled.
# enabled: true
# Whether the foundation is external (does not create target dataset).
# external: false
# Custom table settings file, relative to 'config/' file directory
# Recommended path: '{custom_namespace}/data_product/{data_product_module_type}/table_settings.yaml'
# If omitted, defaults to '../src/data_modules/{custom_namespace}/data_product/{data_product_module_type}/table_settings.default.yaml'
# tableSettings: "{custom_namespace}/data_product/{data_product_module_type}/table_settings.yaml"
- Creación del archivo
tableSettingspredeterminado (p.ej.,src/data_modules/custom_namespace/data_product/data_product_module_type/table_settings.default.yaml).
Este archivo YAML controla las configuraciones de la tabla, como las materializaciones y los detalles de optimización de 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"
- Creación del archivo de anotaciones
El archivo de anotaciones tablename.yaml se crea para cada artefacto de salida del producto de datos (tabla, vista) y describe las columnas y los campos en formato YAML. Durante la compilación, el compilador busca automáticamente anotaciones en la carpeta annotations/ del producto (p.ej., src/data_modules/custom_namespace/data_product/data_product_module_type/annotations/custom_sales_summary.yaml), une estas cadenas directamente en las definiciones del esquema de Dataform de salida para que se conserven en los metadatos de la tabla de BigQuery.
Un archivo de anotaciones src/data_modules/custom_namespace/data_product/data_product_module_type/annotations/tablename.yaml tiene el siguiente formato:
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"
- Crea un archivo
manifest.yamlen tu carpeta de productos de datossrc/data_modules/custom_namespace/data_product/data_product_module_type/, manteniendo el tipo, las tablas y las dependencias del módulo. El archivo de manifiesto tiene el siguiente formato:
type: sales_performance
builder: sap_product # Automatically resolves to the global SapProductBuilder fallback
dependencies:
sapModule:
type: sap
supportedVersions:
- ecc
- s4
Ejemplo de módulo de productos de datos
Los pasos para implementar el producto de datos flights_usd en el espacio de nombres: sap_bookingdatamodel del ejemplo de vuelos son los siguientes:
- Registro del módulo de productos de datos en el archivo
config/config.yaml. Para ello, extiende la listadata.modules.productscon la entrada:
data:
modules:
product:
- moduleId: sap_bookingdatamodel_flights_usd
type: sap_bookingdatamodel.flights_usd
dependsOn:
sapModule: erp
sapModuleCustNS: sap_bookingdatamodel
dataTargetId: product_target
- A continuación, crea
src/data_modules/custom_namespace/data_product/data_product_module_type/manifest.yamlcon el contenido
type: flights_usd
dependencies:
sapModule:
type: cortex.sap
supported_versions:
- ecc
- s4
tables:
common:
- tcurr
sapModuleCustNS:
# Type of the dependent Module.
# use cortex.sap if you followed "Configure multiple instances of a data foundation module"
# https://docs.cloud.google.com/cortex/docs/deployment-configuration#multiple-data-foundation-instances
type: cortex.sap
# use sap_bookingdatamodel.sap if you are connecting to custom-data foundation module:
# https://docs.cloud.google.com/cortex/docs/extensibility-guide-data-foundation
#type: sap_bookingdatamodel.sap
supported_versions:
- ecc
- s4
tables:
common:
- sflight
builder: sap_product
- En el siguiente paso, crea el archivo de configuración de la tabla al que se hace referencia para configurar el esquema y los metadatos de las tablas o vistas de salida en BigQuery.
En el ejemplo utilizado, crea: src/data_modules/custom_namespace/data_product/data_product_module_type/table_settings.default.yaml con el contenido:
ecc:
flights_usd:
materializationType: incremental
tags: [sap, dataproduct, masterdata]
s4:
flights_usd:
materializationType: incremental
tags: [sap, dataproduct, masterdata]
- Crea anotaciones para las tablas de productos de datos para enriquecer el esquema de almacenamiento con descripciones.
En el ejemplo utilizado, crea el archivo: src/data_modules/custom_namespace/data_product/data_product_module_type/annotations/flights_usd.yaml con el contenido:
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"
- La lógica empresarial del producto de datos se almacena en archivos
jsosqlx.
En el ejemplo dado, crea el archivo src/data_modules/custom_namespace/data_product/data_product_module_type/definitions/flights_usd.js con el contenido:
// ___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"])}
`
);
Verificación de la extensión del espacio de nombres personalizado
Para verificar la creación correcta de los módulos de productos de datos de Google Cloud Cortex Framework, sigue estos pasos:
- Ejecuta la implementación de Cortex Framework haciendo referencia al archivo
config.yamlactualizado. - Sigue los pasos posteriores a la implementación para ejecutar las acciones de Dataform y verificar los resultados en BigQuery.
- Paso anterior: Creación del módulo de base de datos
- Paso siguiente: Pasos posteriores a la implementación
- Volver a la descripción general