Créer un module de produit de données
Pour définir votre propre logique métier et vos propres modèles analytiques, créez un module de produit de données personnalisé. Cela vous permet d'effectuer des calculs sur vos tables de base ou vos produits de données en amont, et de regrouper les résultats dans des ensembles de données déployables.
Prérequis
Nous vous recommandons de créer des modules de produits de données personnalisés dans un espace de noms personnalisé dédié pour une meilleure gestion du cycle de vie. Assurez-vous également que la table source que vous prévoyez d'utiliser existe dans l'ensemble de données de base data foundation.
Créer un module de produit de données
La définition d'un module de produit de données nécessite les étapes suivantes :
- Enregistrement du module de produit de données dans le fichier
config/config.yaml, en étendant la listedata.modules.productsavec l'entrée :
data:
# Configuration for data foundation and product modules.
modules:
# List of data product modules.
products:
# Recommended naming for product_module_id:
# custom_namespace_product_name
- moduleId: product_module_id
# Path of the data product (namespaced).
modulePath: custom_namespace.system_type.products.product_name
# Map of module dependencies.
dependencyBindings:
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}/{system_type}/products/{product_name}/table_settings.yaml'
# If omitted, defaults to '../src/data_modules/{custom_namespace}/{system_type}/products/{product_name}/table_settings.default.yaml'
# tableSettings: "{custom_namespace}/{system_type}/products/{product_name}/table_settings.yaml"
- Création du fichier
tableSettingspar défaut (par exemple,src/data_modules/custom_namespace/system_type/products/product_name/table_settings.default.yaml).
Ce fichier YAML contrôle les configurations de table, telles que les matérialisations et les détails d'optimisation BigQuery :
common:
custom_sales_summary:
materializationType: "table"
bigQueryLabels:
- key: data_class
value: transactional
dataformTags: ["custom", "sales", "reporting"]
partitionDetails:
column: "created_date"
partitionType: "date"
timeGrain: "day"
clusterDetails:
columns:
- "customer_id"
- Création d'un fichier d'annotation
Le fichier d'annotation tablename.yaml est créé pour chaque artefact de sortie du produit de données (table, vue) et décrit les colonnes et les champs au format YAML. Lors de la compilation, le compilateur recherche automatiquement les annotations dans le dossier annotations/ du produit (par exemple, src/data_modules/custom_namespace/system_type/products/product_name/annotations/custom_sales_summary.yaml), fusionne ces chaînes directement dans les définitions de schéma Dataform de sortie afin qu'elles soient conservées dans les métadonnées de la table BigQuery.
Un fichier d'annotation src/data_modules/custom_namespace/system_type/products/product_name/annotations/tablename.yaml a le format suivant :
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"
- Créez un fichier
manifest.yamldans le dossier de votre produit de donnéessrc/data_modules/custom_namespace/system_type/products/product_name/, en conservant le type, la catégorie, les tables et les dépendances du module. Le fichier manifeste a le format suivant :
displayName: Sales Performance Summary
description: Sales performance analytical data product.
category: product
type: generic
builder: sap_product # Automatically resolves to the global SapProductBuilder fallback
dependencies:
sapModule:
modulePath: cortex.sap.foundations.sap
supportedVersions:
- ecc
- s4
Exemple de module de produit de données
Voici les étapes à suivre pour implémenter le produit de données flights_usd dans l'espace de noms sap_bookingdatamodel de l'exemple de vols flights example :
- Enregistrement du module de produit de données dans le fichier
config/config.yaml, en étendant la listedata.modules.productsavec l'entrée :
data:
modules:
products:
- moduleId: sap_bookingdatamodel_flights_usd
modulePath: sap_bookingdatamodel.sap.products.flights_usd
dependencyBindings:
sapModule: erp
sapModuleCustNS: sap_bookingdatamodel
dataTargetId: product_target
- Ensuite, créez
src/data_modules/sap_bookingdatamodel/sap/products/flights_usd/manifest.yamlavec le contenu
displayName: Flights USD
description: Flight scheduling and pricing USD data product.
category: product
type: generic
dependencies:
sapModule:
modulePath: cortex.sap.foundations.sap
supportedVersions:
- ecc
- s4
tables:
common:
- tcurr
sapModuleCustNS:
# Type of the dependent Module.
# use cortex.sap.foundations.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
modulePath: cortex.sap.foundations.sap
# use sap_bookingdatamodel.sap.foundations.sap if you are connecting to custom-data foundation module:
# https://docs.cloud.google.com/cortex/docs/extensibility-guide-data-foundation
#modulePath: sap_bookingdatamodel.sap.foundations.sap
supportedVersions:
- ecc
- s4
tables:
common:
- sflight
builder: sap_product
- À l'étape suivante, créez le fichier de paramètres de table référencé pour configurer le schéma et les métadonnées des tables ou des vues de sortie dans BigQuery.
Dans l'exemple utilisé, créez : src/data_modules/sap_bookingdatamodel/sap/products/flights_usd/table_settings.default.yaml avec le contenu :
ecc:
flights_usd:
materializationType: incremental
bigQueryLabels:
- key: data_class
value: transactional
dataformTags: [sap, dataproduct, masterdata]
s4:
flights_usd:
materializationType: incremental
bigQueryLabels:
- key: data_class
value: transactional
dataformTags: [sap, dataproduct, masterdata]
- Créez des annotations pour les tables de produits de données afin d'enrichir le schéma de stockage avec des descriptions.
Dans l'exemple utilisé, créez le fichier : src/data_modules/sap_bookingdatamodel/sap/products/flights_usd/annotations/flights_usd.yaml avec le contenu :
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 logique métier du produit de données est stockée dans des fichiers
jsousqlx.
Dans l'exemple donné, créez le fichier src/data_modules/sap_bookingdatamodel/sap/products/flights_usd/definitions/flights_usd.js avec le contenu :
// ___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"])}
`
);
Vérifier l'extension de l'espace de noms personnalisé
Pour vérifier que les modules de produits de données Google Cloud Cortex Framework ont bien été créés, procédez comme suit :
- Exécutez le déploiement de Cortex Framework en référençant le fichier mis à jour
config.yaml. - Suivez les étapes post-déploiement pour exécuter les actions Dataform et vérifier les résultats dans BigQuery.
- Étape précédente : Créer un module de base de données
- Étape suivante : Étapes post-déploiement
- Retour à la présentation