This repository contains a modern data warehouse (DWH) and analytics platform designed for the Olist Brazilian E-Commerce Dataset (over 1M+ rows of customers, items, reviews, and geo coordinates).
It implements a complete end-to-end ELT pipeline using DuckDB as the local OLAP database, dbt Core for Kimball dimensional transformations, Astronomer Cosmos & Apache Airflow for orchestrating task groups, Bruin CLI for connection and lineage testing, and Evidence.dev for BI dashboarding.
- Storage & Query Engine: DuckDB (
ecommerce.db) - extremely fast vectorized local columnar database. - Transformation: dbt Core (
dbt-duckdbadapter) - modular SQL compiling, dependency graphs, and documentation. - Orchestration: Apache Airflow & Astronomer Cosmos - schedules the python ingestion and compiles dbt projects dynamically into Airflow tasks.
- Validation & Lineage: Bruin CLI - fast validation of sql syntax, query rendering, and local connections.
- Reporting (BI): Evidence.dev - markdown-based static BI dashboard querying DuckDB natively.
- Formatting & Quality: SQLFluff - SQL linter to enforce style guides.
- Package Management: uv - Astral's lightning-fast Rust-based Python packaging tool.
When running the platform locally, the following interfaces are available:
π URL: http://localhost:3000 - Dynamic cohorts, sales growth, and product rankings.
π URL: http://localhost:8080 - Task execution DAG graphs, schedule runs, and execution logs.
ecommerce-data-modeling/
βββ .env # Local environment variables (paths)
βββ .env.example # Environment variables template
βββ .sqlfluff # Linter formatting configuration
βββ .gitignore # Git exclusions for db, target, logs
βββ requirements.txt # Python dependencies (dbt, duckdb, airflow, cosmos)
βββ README.md # Project overview & documentation
βββ dataset/ # Raw Olist CSV files
β βββ olist_customers_dataset.csv
β βββ ...
βββ scripts/
β βββ ingest.py # Vectorized Python script to load CSVs into DuckDB
βββ dbt_project/ # dbt Project root
β βββ dbt_project.yml # dbt settings (staging, intermediate, marts schemas)
β βββ profiles.yml # DuckDB adapter configurations
β βββ packages.yml # dbt dependencies (dbt_utils)
β βββ models/
β βββ staging/ # Staging views (1:1 maps, type casting, renaming)
β βββ intermediate/ # Intermediate views (payment and review rollups, joins)
β βββ marts/ # Star Schema analytics tables (dim_ & fct_)
βββ airflow/ # Airflow configurations
β βββ dags/
β βββ run_lakehouse.py # Cosmos orchestrator DAG
βββ dashboard/ # Evidence.dev Dashboard
βββ pages/
βββ index.md # Markdown-based dashboard reports
We use uv to manage virtual environments (.venv) and Python packages cleanly and at maximum speed.
Install uv globally on your Linux system:
curl -LsSf https://astral.sh/uv/install.sh | shCreate a localized virtual environment inside the project directory:
# Create the .venv folder
uv venv
# Activate the virtual environment
source .venv/bin/activateInstall all required libraries (dbt, duckdb, cosmos, airflow, sqlfluff) specified in requirements.txt:
uv pip install -r requirements.txtThe pipeline uses environment variables to resolve absolute paths dynamically (preventing relative path breaks inside Airflow).
- Copy the template:
cp .env.example .env
- Open
.envand verify the paths align with your workspace:PROJECT_ROOT=/home/tunguyenn99/my-project/ecommerce-data-modeling AIRFLOW_HOME=/home/tunguyenn99/my-project/ecommerce-data-modeling DBT_PROFILES_DIR=/home/tunguyenn99/my-project/ecommerce-data-modeling/dbt_project DB_PATH=/home/tunguyenn99/my-project/ecommerce-data-modeling/ecommerce.db
Run the ingestion script to bulk copy the raw CSVs into DuckDB's raw schema:
# Ensure virtual env is active
uv run python scripts/ingest.pyThis creates the ecommerce.db file and loads over 1.5 million records across 9 tables in less than 1.0 second.
Navigate into the dbt project folder and download required macro libraries:
cd dbt_project
dbt depsCompile staging models, build aggregated intermediate layers, materialize star-schema fact/dimensions tables, and execute testing blocks:
# Test connection compatibility
dbt debug --profiles-dir .
# Materialize views and tables (creates schemas: main_staging, main_intermediate, main_marts)
dbt run --profiles-dir .
# Run all unique, null, and relationship constraint tests (32 tests total)
dbt test --profiles-dir .Bruin CLI is pre-configured via .bruin.yml to communicate with the DuckDB database.
# Navigate back to project root
cd ..
# Verify connections list
bruin connections list
# Query fact tables directly via Bruin CLI
bruin query --connection duckdb-default --query "select * from main_marts.fct_monthly_kpis limit 5" --description "Verify monthly kpis"Connect the visual frontend to DuckDB and launch the interactive analytics server:
cd dashboard
npm install
npm run devOpen http://localhost:3000 in your browser to view cohort maps, revenue growth metrics, and product category rankings.
The pipeline maps the Olist database to a clean Star Schema:
dim_customers: Deduplicated geographic demographics (State, City, coordinates) mapped to customer accounts.dim_products: Product dimensions translated to English category labels.dim_sellers: Seller records supplemented with geolocation coordinates.fct_orders: Grain at the order level, summing totals, payment divisions, review rankings, and shipping delays.fct_order_items: Grain at the order line-item level.fct_monthly_kpis: Monthly financial, traffic, and rating aggregation matrix.
- Author: Tu Nguyen
- Community: Join the Xom Data community for more data analytics engineering insights!
Built with β€οΈ for the Xom Data community.



