Creazione del modulo della base dati
Sebbene Cortex Framework fornisca moduli della base dati predefiniti per i sistemi ERP aziendali come SAP (cortex.sap), puoi anche creare nuovi moduli della base dati personalizzati all'interno di uno spazio dei nomi personalizzato. In questo modo puoi definire comportamenti di compilazione personalizzati ed estendere il supporto a un nuovo sistema di origine. Questi possono includere sistemi di gestione di database come PostgreSQL, MySQL e così via che replicano i dati non elaborati in BigQuery.
Questa guida illustra un esempio end-to-end di creazione di un nuovo modulo della base dati per un sistema di gestione dei ticket di assistenza clienti i cui dati (tabelle customers, tickets, ticketlogitem) sono stati replicati da un database PostgreSQL in un set di dati BigQuery non elaborato denominato ticketing_data_raw.
Quando crei un modulo della base dati personalizzato, ti consigliamo di utilizzare uno spazio dei nomi personalizzato dedicato per migliorare la gestione del ciclo di vita separando le estensioni e le personalizzazioni dagli artefatti di Cortex Framework.
Panoramica dello scenario di esempio
In questa procedura dettagliata:
- Creeremo uno spazio dei nomi personalizzato dedicato
ticketingper isolare gli asset della base dati. - Definiremo un nuovo modulo della base dati con il percorso
ticketing.ticketing.foundations.ticketing_system. - Configureremo le impostazioni della tabella (
table_settings.default.yaml) per le tabellecustomers,ticketseticketlogitem. - Creeremo annotazioni di metadati a livello di colonna e campo per ogni tabella.
- Registreremo l'origine dati non elaborata (
ticketing_data_raw), il set di dati di destinazione conforme (data_foundation_ticketing) e il nuovo modulo della base inconfig/config.yaml.
Struttura di cartelle e file del modulo
Tutti i file fisici del nuovo modulo della base dati si trovano all'interno dello spazio dei nomi personalizzato in src/data_modules/. La tabella e la struttura di directory seguenti descrivono dove inserire ogni file:
config/
└── config.yaml # Global configuration & module registration
src/data_modules/ticketing/ticketing/foundations/ticketing_system/
├── manifest.yaml # Declares module category, type, and builder
├── table_settings.default.yaml # Table materialization, bigQueryLabels, dataformTags, and layouts
├── builder.py # (Optional) Custom Dataform generator class for this module
└── annotations/ # Field and column-level schema descriptions
├── customers.yaml
├── tickets.yaml
└── ticketlogitem.yaml
Importante: prima di iniziare, assicurati che le tabelle di origine che prevedi di elaborare esistano nel set di dati del livello non elaborato.
| Percorso del file o della directory | Scopo e descrizione |
|---|---|
config/config.yaml |
Registra lo spazio dei nomi ticketing, l'origine dati non elaborata PostgreSQL, il set di dati BigQuery di destinazione e l'istanza del modulo della base. |
src/data_modules/ticketing/ticketing/foundations/ticketing_system/manifest.yaml |
Dichiara i metadati del modulo, il nome visualizzato, la categoria (ad es. foundation), il tipo di modulo (ad es. generic) e la classe del generatore utilizzata durante la compilazione. |
src/data_modules/ticketing/ticketing/foundations/ticketing_system/table_settings.default.yaml |
Configura le tabelle di origine di ticketing_data_raw che devono essere conformi, insieme a dataformTags, bigQueryLabels, dettagli della partizione e dettagli del cluster di ottimizzazione di BigQuery. |
src/data_modules/ticketing/ticketing/foundations/ticketing_system/annotations/*.yaml |
Contiene metadati YAML avanzati che descrivono le definizioni di tabelle e campi. Questi vengono uniti automaticamente nelle definizioni Dataform compilate, in modo che le descrizioni persistano nei metadati della tabella BigQuery. |
src/data_modules/ticketing/ticketing/foundations/ticketing_system/builder.py |
Facoltativo. Se il database di origine richiede la pulizia dei dati personalizzata o trasformazioni SQL specifiche del dialetto durante la compilazione, puoi definire una classe di compilazione a livello di modulo qui. |
Passaggio 1: registra lo spazio dei nomi, l'origine dati e la destinazione in config.yaml
Prima di creare i file fisici, apri il file di configurazione del deployment (config/config.yaml) e dichiara lo spazio dei nomi personalizzato, il set di dati di origine PostgreSQL non elaborato e il set di dati di destinazione in cui verranno create le tabelle conformi:
data:
namespaces:
- name: cortex
path: ../src/data_modules/cortex
- name: ticketing # <-- Name of custom namespace
path: ../src/data_modules/ticketing # <-- Points to subdirectory under 'src/data_modules/'
datasets:
- id: ticketing_data_raw # <-- Unique source ID
projectId: "source_project_id"
datasetId: ticketing_data_raw # <-- Raw dataset containing PostgreSQL replication tables
- id: data_foundation_ticketing # <-- Unique target ID
projectId: "target_project_id"
datasetId: data_foundation_ticketing # <-- Target dataset for conformed foundation tables
Passaggio 2: registra il modulo della base dati in config.yaml
Nella sezione data.modules.foundations di config/config.yaml, registra la nuova istanza del modulo della base dati, collegando l'origine dati (ticketing_data_raw) alla destinazione dati (data_foundation_ticketing):
data:
modules:
foundations:
- moduleId: ticketing_foundation
modulePath: ticketing.ticketing.foundations.ticketing_system # Format: {namespace}.{systemtype}.{module_type:foundations}.{subsystemtype}
dataSourceId: ticketing_data_raw
dataTargetId: data_foundation_ticketing
# Custom table settings file relative to 'config/' directory
# Recommended path: '{namespace_dir}/{system_type}/foundations/{system_sub_type}/table_settings.yaml'
# If omitted, defaults to "../src/data_modules/ticketing/ticketing/foundations/ticketing_system/table_settings.default.yaml"
tableSettings: "ticketing/ticketing/foundations/ticketing_system/table_settings.yaml"
Passaggio 3: crea il file manifest del modulo
Crea il file manifest che dichiara i metadati del modulo: src/data_modules/ticketing/ticketing/foundations/ticketing_system/manifest.yaml.
displayName: Ticketing System Data Foundation
description: Conformed foundation tables for PostgreSQL raw ticketing database.
category: foundation
type: generic
builder: ticketing_foundation
Passaggio 4: crea il file delle impostazioni della tabella (table_settings.default.yaml)
Crea il file di configurazione della tabella predefinita src/data_modules/ticketing/ticketing/foundations/ticketing_system/table_settings.default.yaml. Questo file definisce come le tabelle PostgreSQL replicate (customers, tickets, ticketlogitem) vengono materializzate, partizionate e raggruppate in cluster in BigQuery:
common:
- source:
tableName: customers
target:
bigQueryLabels:
- key: data_class
value: master
dataformTags: [ticketing, foundation, masterdata]
clusterDetails:
columns: [customer_id]
- source:
tableName: tickets
target:
bigQueryLabels:
- key: data_class
value: transactional
dataformTags: [ticketing, foundation, transactional]
partitionDetails:
column: created_at
partitionType: time
timeGrain: day
clusterDetails:
columns: [ticket_id, customer_id]
- source:
tableName: ticketlogitem
target:
bigQueryLabels:
- key: data_class
value: transactional
dataformTags: [ticketing, foundation, transactional]
partitionDetails:
column: log_timestamp
partitionType: time
timeGrain: day
clusterDetails:
columns: [ticket_id, log_id]
Passaggio 5: crea annotazioni di metadati a livello di campo
Per assicurarti che le tabelle conformi contengano una documentazione chiara in BigQuery, crea un file YAML di annotazione per ogni tabella all'interno di src/data_modules/ticketing/ticketing/foundations/ticketing_system/annotations/. Il nome file deve corrispondere esattamente al nome della tabella di origine.
annotations/customers.yaml
description: "Customer master data conformed from PostgreSQL raw ticketing database."
fields:
- name: "customer_id"
description: "Unique customer identifier, PK"
- name: "email"
description: "Primary email address associated with the customer"
- name: "full_name"
description: "Customer full name or account contact name"
- name: "created_at"
description: "Timestamp when the customer record was originally created in PostgreSQL"
annotations/tickets.yaml
description: "Customer service tickets conformed from PostgreSQL raw ticketing database."
fields:
- name: "ticket_id"
description: "Unique ticket identifier, PK"
- name: "customer_id"
description: "Foreign key referencing customers.customer_id"
- name: "subject"
description: "Summary or subject line of the customer inquiry"
- name: "status"
description: "Current ticket lifecycle status (e.g., OPEN, IN_PROGRESS, RESOLVED, CLOSED)"
- name: "priority"
description: "Priority severity level (e.g., LOW, MEDIUM, HIGH, URGENT)"
- name: "created_at"
description: "Timestamp when the ticket was created"
- name: "updated_at"
description: "Timestamp when the ticket was last modified"
annotations/ticketlogitem.yaml
description: "Audit log history and activity events for customer service tickets."
fields:
- name: "log_id"
description: "Unique log event identifier, PK"
- name: "ticket_id"
description: "Foreign key referencing tickets.ticket_id"
- name: "action"
description: "Action or event performed on the ticket"
- name: "description"
description: "Notes and description on performed events on the ticket"
- name: "performed_by"
description: "User, agent, or automated system that performed the action"
- name: "log_timestamp"
description: "Exact timestamp when the activity log event occurred"
Passaggio 6: (facoltativo) definisci un generatore della base personalizzato
Se la base dati PostgreSQL richiede una logica durante la compilazione (ad esempio regole di conversione automatica del tipo di dati, conversione del timestamp o pulizia dei dati in tutte le tabelle), puoi definire un generatore personalizzato con ambito limitato a questo modulo.
Crea src/data_modules/ticketing/ticketing/foundations/ticketing_system/builder.py:
import logging
import pathlib
import yaml
from common.builders.base import FoundationBuilder, Source
from common.registry import builder_registry
from common.schemas import config_schema, manifest_schema
logger = logging.getLogger(__name__)
@builder_registry.register("ticketing_foundation")
class TicketingFoundationBuilder(FoundationBuilder[config_schema.BaseModuleConfig]):
"""Custom Dataform generator for PostgreSQL ticketing data foundation."""
def build(
self,
*,
module_id: str,
module_config: config_schema.BaseModuleConfig,
global_config: config_schema.GlobalConfig,
manifest: manifest_schema.ManifestConfig,
base_dir: pathlib.Path,
annotations_dir: pathlib.Path,
output_dir: pathlib.Path,
module_dir_name: str,
sources_registry: set[Source],
table_settings_file: pathlib.Path | None = None,
required_tables: set[str] | None = None,
) -> None:
logger.info("Building ticketing data foundation for module: %s", module_id)
# 1. Load table settings
if not table_settings_file or not table_settings_file.exists():
logger.warning("No valid table settings found for %s", module_id)
return
with open(table_settings_file, encoding="utf-8") as f:
settings = yaml.safe_load(f) or {}
tables = settings.get("common", [])
source_config = global_config.get_data_source(module_config.data_source_id)
target_dataset = global_config.get_data_target(module_config.data_target_id)
# 2. Generate Dataform .sqlx files for each table
for table_item in tables:
source_table = table_item["source"]["tableName"]
if required_tables and source_table not in required_tables and not table_item.get("deployAlways"):
continue
# Register source table for centralized source generation
sources_registry.add(Source(source_config.project_id, source_config.dataset_id, source_table))
# Retrieve labels if configured
bigquery_config = {}
if "bigQueryLabels" in table_item["target"]:
labels_dict = {label["key"]: label["value"] for label in table_item["target"]["bigQueryLabels"]}
bigquery_config["labels"] = labels_dict
dataform_tags = table_item["target"].get("dataformTags", ["ticketing", "foundation"])
sqlx_content = f"""config {{
type: "table",
schema: "{target_dataset.dataset_id}",
name: "{source_table}",
tags: {dataform_tags}"""
if bigquery_config:
sqlx_content += f",\n bigquery: {bigquery_config}"
sqlx_content += f"""
}}
SELECT *
FROM `${{source_config.project_id}}.${{source_config.dataset_id}}.{source_table}`
"""
out_file = output_dir / f"{source_table}.sqlx"
out_file.write_text(sqlx_content, encoding="utf-8")
logger.info("Generated %s", out_file)
Verifica del nuovo modulo della base
Per verificare ed eseguire il deployment del modulo della base dati appena creato:
- Esegui lo script di compilazione ed esecuzione del deployment di Cortex Framework:
bash uv run cortex-build-and-deploy --config "config/config.yaml" - Verifica che la compilazione di Dataform sia riuscita senza errori e che siano stati generati script
.sqlxpercustomers,ticketseticketlogitem. - Segui i passaggi successivi al deployment per eseguire le azioni della pipeline Dataform e verificare i record conformi all'interno del set di dati
data_foundation_ticketingin BigQuery.
Per verificare che il modulo della base dati personalizzato venga compilato ed eseguito il deployment correttamente, consulta la sezione Verifica nella pagina Estensibilità del prodotto dati.
- Passaggio precedente: configurazione di uno spazio dei nomi personalizzato
- Passaggio successivo: creazione del modulo del prodotto dati
- Torna alla panoramica