This guide provides a comprehensive overview of the data pipeline architecture in the dbt SQL Server Learning Project. It outlines the strategic approach to transforming raw data into business-ready insights using the Medallion Architecture and Analytics Engineering best practices.
The project is structured into three distinct functional layers to ensure data quality, traceability, and performance.
- Purpose: Ingests raw data from source systems "as-is" with no transformations.
- Characteristics: Preserve history, retain all columns (mostly `VARCHAR`), and allow nulls/duplicates.
- Location: `TestDB.bronze.*` (e.g., `bronze.customers`).
- dbt Role: Defined as Sources in `schema.yml`.
- Purpose: Standardizes data types, fixes formatting issues, handles NULLs, and enforces business rules.
- Characteristics: One-to-one mapping with Bronze tables but with cleaned data (ISO dates, boolean flags, imputed values).
- Location: `TestDB.silver.*` (e.g., `silver.customers`).
- dbt Role: Staging & Intermediate Models. This is where the bulk of transformation logic resides.
- Purpose: Business-focused aggregations, dimension models, and fact tables ready for BI tools.
- Characteristics: Join multiple silver tables, optimized for reporting, high-level abstractions (e.g., `dim_customers`, `fact_sales`).
- Location: `TestDB.gold.*`.
- dbt Role: Mart Models.
Organize your models directory by layer to keep the project maintainable:
models/
│
├── staging/
│ ├── src_customers.sql
│ ├── src_orders.sql
│ ├── src_products.sql
│ ├── src_inventory.sql
│ ├── src_stores.sql
│ ├── src_payments.sql
│ └── src_shipments.sql
│
├── intermediate/
│ │
│ ├── customers/
│ │ ├── int_customers_contact.sql
│ │ ├── int_customers_location.sql
│ │ ├── int_customers_dates.sql
│ │ └── int_customers_standardized.sql
│ │
│ ├── employees/
│ │ ├── int_employees_contact.sql
│ │ └── int_employees_standardized.sql
│ │
│ ├── products/
│ │ ├── int_products_standardized.sql
│ │ └── int_products_categories.sql
│ │
│ ├── transactions/
│ │ ├── int_transactions_deduplicated.sql
│ │ └── int_transactions_validated.sql
│
├── marts/
│ │
│ ├── dimensions/
│ │ ├── dim_customers.sql
│ │ ├── dim_products.sql
│ │ ├── dim_employees.sql
│ │ └── dim_stores.sql
│ │
│ ├── facts/
│ │ ├── fct_orders.sql
│ │ ├── fct_inventory.sql
│ │ ├── fct_payments.sql
│ │ └── fct_shipments.sql
│ │
│ └── reporting/
│ ├── sales_summary.sql
│ ├── inventory_summary.sql
│ └── employee_performance.sql
│
├── tests/
├── macros/
└── seeds/
Define all raw tables in a `sources.yml` file. This allows you to:
- Reference sources safely: Use `{{ source('bronze', 'customers') }}` instead of hardcoded table names.
- Implement Freshness Checks: Ensure your raw data is up-to-date.
- Apply Early Tests: Check for `not_null` and `unique` on primary keys (e.g., `customer_id`) at the source level.
When building models in the silver layer, follow these design patterns:
- Standardization: Convert all dates to ISO 8601 (`YYYY-MM-DD`) and booleans to a consistent format.
- Reference: See `explore_database/customers/bronze_account_create_date.md` for a deep dive into date cleaning logic.
- NULL Handling:
- Preservation: Keep NULLs if they have business meaning (e.g., `loyalty_points`).
- Standardization: Convert blanks/line breaks to `'Unknown'`.
- Imputation: Use statistical methods (like median income) for missing numeric data when requested by business rules.
- CTE-First Approach: Use Common Table Expressions (CTEs) to break down complex logic into readable steps (e.g., `cleaning`, `standardizing`, `final_select`).
Leverage the `meta` tag in `schema.yml` to capture business context that SQL cannot express.
- Describe transformations: Document why a certain logic was chosen.
- Standardize values: List expected categorical values (e.g., `gender`, `preferred_channel`).
- Data Quality Notes: Warn downstream users about known data issues (e.g., duplicate IDs in source).
A pipeline is only as good as its tests. Use dbt's built-in testing suite:
| Test Type | Purpose | Example |
|---|---|---|
| Generic Tests | Standard checks for constraints. | `unique`, `not_null`, `accepted_values`, `relationships`. |
| Singular Tests | Custom SQL queries that should return 0 rows. | Ensuring `refund_amount` is never greater than `order_amount`. |
| Source Freshness | Alerts if data ingestion stops. | Error if `raw_sales` is older than 24 hours. |
- Define Source: Add the raw table to `models/silver/schema.yml` under the `bronze` source.
- Create SQL Model:
- Create `models/silver/new_model.sql`.
- Import source using `{{ source('bronze', '...') }}`.
- Apply cleaning and standardization logic.
- Document & Test: Add descriptions and tests to `schema.yml`.
- Run & Validate: ```bash dbt run --select new_model dbt test --select new_model ```
- Review Lineage: Use `dbt docs generate && dbt docs serve` to verify the dependency graph.
To reach full maturity, the project should move towards Dimensional Modeling (Star Schema):
- Dimensions: Slow-changing entities like `dim_customers`, `dim_products`.
- Facts: Immutable events like `fact_transactions`, `fact_inventory`.
- Snapshots: Use dbt snapshots to track historical changes in source records.
Created by Ritik CLI Ai agent for the dbt SQL Server Learning Project.
git commit -m "message about commit
Co-authored-by: ritsky-project <ritsky598@gmail.com>"