Bridging Code-First and Metadata-First Approaches
From dbt to MDDE — Bridging Code-First and Metadata-First Approaches
If dbt works — Why introduce something like MDDE?
For many teams, dbt is the modern data stack.
It provides:
- Clean SQL-based transformations
- Dependency graphs
- Tests and documentation
- Developer-friendly workflows
It has raised the quality bar across the industry.
So if dbt works — why introduce something like MDDE?
The answer is not replacement.
It’s enrichment.

Code-First vs Metadata-First
dbt is unapologetically code-first.
Models are defined as SQL files.
Structure is inferred.
Documentation and tests are attached via YAML.
It works beautifully for:
- Analytics engineering
- Rapid iteration
- Clean transformation pipelines
But as systems scale, some patterns emerge:
- Semantics live partly in SQL and partly in YAML
- Entity meaning is implied rather than modeled
- Reusable expressions get duplicated
- Governance is external to the project
- Cross-model lineage becomes hard to reason about
None of these are flaws.
They are natural consequences of code-first design.
MDDE approaches the same landscape from a different angle.
It is metadata-first.
What Metadata-First Actually Means
Metadata-first does not mean “no SQL.”
It means:
- Logical entities are explicit
- Attributes are first-class objects
- Relationships are materialized
- Mappings are structured
- Functions are reusable artifacts
- Lineage is stored, not inferred
SQL becomes one projection of that metadata.
Not the only one.
The Bridge: Import dbt into MDDE
This is not a rewrite.
It’s an import.
python -m mdde.importer.dbt_importer path/to/dbt_project --name my_analytics
MDDE extracts:
- Models as logical entities
- Sources and refs as relationships
- Column lineage from SQL parsing
- Tests as quality metadata
- Documentation as conceptual layer
Then you can analyze:
python -m mdde.scripts.analyze_model mdl_analytics --verbose
Now structure becomes inspectable.
What Changes After Import?
In dbt alone:
models/
staging/stg_customers.sql
marts/dim_customer.sql
schema.yml
In MDDE workspace:
workspace/applications/dbt/my_analytics/
entities/customer/
entity.conceptual.yaml
entity.logical.yaml
mappings/
diagrams/
You gain:
- Explicit entity folders
- Column-level lineage
- Relationship metadata
- Function extraction opportunities
- Optimizer passes
- Compliance scoring
- Multi-dialect DDL generation
Without breaking dbt.
Enrich → Export → Keep dbt Execution
After enrichment, you can export back.
python -m mdde.scripts.export_model mdl_analytics \
--output path/to/dbt_project \
--generate-dbt
You keep:
- dbt execution model
- dbt run
- dbt test
- dbt documentation
But now with:
- Cleaner structure
- Extracted reusable logic
- Explicit metadata
- Enterprise governance overlay
It’s not dbt vs MDDE.
It’s dbt + MDDE.
When This Matters Most
The bridge becomes powerful when:
- Multiple dbt projects need governance alignment
- Migration to new platforms is required
- Regulatory lineage is mandatory
- Data quality must propagate across models
- You need DDL generation outside dbt’s scope
dbt remains execution engine.
MDDE becomes structure engine.
Architectural Positioning
Think of it like this:
dbt answers:
“How should this transformation run?”
MDDE answers:
“What is this transformation structurally?”
Those are different questions.
Both matter.
Why This Is Not Redundant
You could manually maintain:
- Conceptual diagrams
- Governance spreadsheets
- Cross-project lineage tools
Or you can extract structure directly from SQL and enrich it systematically.
The latter scales better.
Especially in multi-team environments.
The Combined Workflow
dbt SQL
↓
MDDE Import
↓
Metadata Enrichment
↓
Optimization & Governance
↓
Export Back to dbt
SQL remains the execution surface.
Metadata becomes the structural backbone.
Built for VSCode Workflows
This entire bridge works in VSCode.
You edit SQL.
You run the MDDE scripts.
You inspect metadata.
You review diffs.
You regenerate artifacts.
AI assistance (Claude Code) accelerates modeling tasks,
but the metadata structure remains deterministic.
Closing
This is not a philosophical argument.
It’s a practical bridge.
If you’re happy with dbt — you should be.
MDDE doesn’t compete with it.
It complements it.
And in complex environments, that difference becomes significant.
Next in the Series
In the next article:
Enterprise Model Import — PowerDesigner, erwin, Hackolade, ArchiMate
We’ll explore how MDDE:
- Preserves legacy modeling investments
- Imports structured metadata from enterprise tools
- Modernizes models into Git-native YAML
- Enables migration without vendor lock-in
🔧 Technical Deep Dive — Importing dbt Models
After dbt import:
python -m mdde.importer.dbt_importer path/to/dbt_project \
--name analytics_model
Inspect imported entities:
SELECT entity_name, stereotype
FROM metadata.entity
WHERE model_id = 'mdl_analytics';
Inspect ref-based relationships:
SELECT
parent.entity_name AS parent_model,
child.entity_name AS child_model
FROM metadata.relationship r
JOIN metadata.entity parent ON r.parent_entity_id = parent.entity_id
JOIN metadata.entity child ON r.child_entity_id = child.entity_id
WHERE parent.model_id = 'mdl_analytics';
dbt dependency graph becomes structured metadata.