יצירת מודול של מוצר נתונים

כדי להגדיר לוגיקה עסקית ומודלים אנליטיים משלכם, אתם יכולים ליצור מודול מותאם אישית של מוצר נתונים. כך תוכלו להריץ חישובים על טבלאות הבסיס או על מוצרי נתונים במעלה הזרם, ולארוז את התוצאות במערכי נתונים שניתן לפרוס.

דרישות מוקדמות

כדי לשפר את ניהול מחזור החיים, מומלץ ליצור מודולים של מוצרי נתונים בהתאמה אישית במרחב שמות מותאם אישית ייעודי. בנוסף, מוודאים שטבלת המקור שבה אתם מתכננים להשתמש קיימת במערך הנתונים של הבסיס לנתונים.

יצירה של מודול מוצר נתונים

כדי להגדיר מודול של מוצר נתונים, צריך לבצע את השלבים הבאים:

  • רישום של מודול נתוני המוצרים בקובץ config/config.yaml, על ידי הרחבת הרשימה data.modules.products עם הרשומה:
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"
        
  • יצירה של קובץ ברירת מחדל tableSettings (לדוגמה, src/data_modules/custom_namespace/data_product/data_product_module_type/table_settings.default.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. במהלך ההידור, כלי ה-builder מחפש באופן אוטומטי אנוטציות בתיקייה annotations/ של המוצר (לדוגמה, src/data_modules/custom_namespace/data_product/data_product_module_type/annotations/custom_sales_summary.yaml), ממזג את המחרוזות האלה ישירות להגדרות של סכימת הפלט של Dataform, כך שהן נשמרות במטא-נתונים של טבלה ב-BigQuery.

קובץ ההערות src/data_modules/custom_namespace/data_product/data_product_module_type/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"
  • יוצרים קובץ manifest.yaml בתיקיית מוצר הנתונים src/data_modules/custom_namespace/data_product/data_product_module_type/, תוך שמירה על הסוג, הטבלאות והתלות במודולים. קובץ המניפסט צריך להיות בפורמט הבא:

type: sales_performance
builder: sap_product     # Automatically resolves to the global SapProductBuilder fallback
dependencies:
  sapModule:
    type: sap
    supportedVersions:
      - ecc
      - s4

דוגמה למודול של מוצר נתונים

השלבים להטמעת מוצר הנתונים flights_usd במרחב השמות: sap_bookingdatamodel של הדוגמה לנתוני טיסות הם:

  • רישום של מודול נתוני המוצרים בקובץ config/config.yaml, על ידי הרחבת הרשימה data.modules.products עם הרשומה:
data:
  modules:
    product:
      - moduleId: sap_bookingdatamodel_flights_usd
        type: sap_bookingdatamodel.flights_usd
        dependsOn:
          sapModule: erp
          sapModuleCustNS: sap_bookingdatamodel
        dataTargetId: product_target
  • בשלב הבא, יוצרים את src/data_modules/custom_namespace/data_product/data_product_module_type/manifest.yaml עם התוכן
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
  • בשלב הבא, יוצרים את קובץ הגדרות הטבלה שאליו מתייחסים כדי להגדיר את הסכימה והמטא-נתונים של טבלאות או תצוגות הפלט ב-BigQuery.

בדוגמה שבה השתמשנו, יצרנו את src/data_modules/custom_namespace/data_product/data_product_module_type/table_settings.default.yaml עם התוכן:

ecc:
  flights_usd:
    materializationType: incremental
    tags: [sap, dataproduct, masterdata]
s4:
  flights_usd:
    materializationType: incremental
    tags: [sap, dataproduct, masterdata]

  • כדי להוסיף תיאורים לסכימת האחסון, יוצרים הערות לטבלאות של מוצרי נתונים.

בדוגמה שבה השתמשנו, יוצרים את הקובץ src/data_modules/custom_namespace/data_product/data_product_module_type/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/data_product/data_product_module_type/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, פועלים לפי השלבים הבאים: