The framework is designed as a banking-oriented ingestion kernel for Databricks-style platforms.
It aims to solve four things together:
- governed ingestion into Bronze
- curated state handling in Silver
- semantic publication into Gold
- persisted operational and control evidence
The design stays deliberately smaller than a full enterprise platform. It gives you the core execution and control model, while leaving approval workflows, enterprise access policy, and broader data-product governance outside the repo.
SourceContract describes the inbound dataset.
It owns source-side concerns such as:
- source identifiers
- expected and mandatory columns
- primary keys
- schema mode
- quality expectations
- format-specific adapter options
Examples:
- file ingestion source
- Bronze table used as Silver promotion input
- XLSX sheet-driven source
DatasetTarget describes where the dataset is published and how that target behaves.
It owns target-side concerns such as:
catalog.schema.table- medallion stage
- state model
- managed storage path
This split is intentional:
SourceContractsays what the source promisesDatasetTargetsays how the target should behave
Adapters convert one source type into an IngestionDataset.
Current adapters:
CsvSourceAdapterXlsxSourceAdapterSparkTableSourceAdapterStaticSourceAdapterfor tests
These adapters normalize source behavior into one pipeline contract, even though the actual source forms are different.
The pipeline layer orchestrates:
- discovery
- schema validation
- quality evaluation
- technical metadata enrichment
- stage preparation
- persistence
- tracker state changes
- audit emission
Concrete pipelines:
FileToBronzePipelineFileToSilverPipeline
Shared orchestration:
BaseIngestionPipeline
The framework persists several kinds of state:
- target table writes via
DeltaRepository - file-tracker state via
TrackerStore - audit history via
AuditLogger - quarantine outputs for failed validation
- reconciliation evidence via
DeltaReconciliationStore
src/databricks_ingestion/
adapters/ source readers: csv, xlsx, table
audit/ audit events and Delta persistence
contracts/ source and target definitions
pipelines/ orchestration and stage-specific logic
policies/ schema, quality, bronze, scd2
runtime/ Spark/runtime bootstrapping
storage/ Delta repository and tracker state
job_config.py config parsing for bundle-style jobs
job_runner.py execution helpers for jobs
jobs.py public façade / CLI entrypoint
reconciliation.py controls and persisted evidence
semantics.py Gold semantic publication
landing files
-> adapter discovery
-> processed-file filtering
-> source read
-> schema policy
-> quality policy
-> Bronze metadata enrichment
-> append-only Delta write
-> tracker success
-> audit success
Bronze is designed to answer:
What arrived, from where, and under which run context?
Preferred Silver flow:
Bronze table/view
-> SparkTableSourceAdapter
-> schema policy
-> quality policy
-> stage preparation
-> append/latest/scd2 write
-> reconciliation controls
Silver is designed to answer:
What is the curated business record or business state?
curated Silver table/view
-> SemanticViewSpec
-> optional joins
-> dimensions / measures / filters
-> Gold table or view
-> semantic metadata properties
-> reconciliation controls
Gold is designed to answer:
What is the trusted output for analytics, controls, or reporting?
contract:
source_id: customer_accounts
source_system: bank_feed
format: csv
landing_path: /Volumes/main/raw/customer_accounts
primary_keys: [account_id]
target:
catalog: main
schema: banking
dataset_name: customer_accounts
stage: bronzeOutcome:
- rows land append-only in
main.banking.customer_accounts_bronze - file-level lineage is stamped into the table
- tracker and audit state are persisted separately
contract:
format: table
landing_path: main.banking.customer_accounts_bronze
table_options:
source_table: main.banking.customer_accounts_bronze
target:
stage: silver
state_model: scd2Outcome:
- Silver does not reread landing files
- Silver state is promoted from governed Bronze
- current and historical versions are handled in the curated layer
semantic_spec:
name: customer_accounts_summary
source_table: main.banking.customer_accounts_silver AS accounts
shared_measures:
- name: total_amount
expression: sum(accounts.amount)
measure_refs: [total_amount]
materialization: tableOutcome:
- a Gold table is published from curated Silver
- semantic metadata is written to table properties
- reconciliation controls can block publication
This architecture is useful because it separates three concerns that often get mixed:
- source truth
- curated state
- published semantics
That makes it much easier to reason about:
- lineage
- controls
- ownership
- replay
- BCBS239-style evidence
This repo is not trying to own:
- enterprise workflow approval
- enterprise access policy enforcement
- enterprise semantic serving APIs
- full product-registry or marketplace behavior
Those layers can sit above the framework, while the framework remains the ingestion and control kernel.