← All work
Data Engineer (team of 2)2025

Food Inspection Analytics

A data engineering platform that unifies food-safety inspection data from Chicago and Dallas into a Medallion (Bronze→Silver→Gold) lakehouse, powering cross-city compliance and risk-hotspot analytics in Tableau.

Multi-city food inspection analytics platform
2
Cities unified
2
Source shapes
3
Medallion layers
25
Dallas violation blocks
5
Gold entities
4
Star dimensions

The problem

Two shapes, no shared schema

Chicago

Long

Chicago Department of Public Health

Violations arrive as

Every violation packed into one pipe-delimited string

Severity

Rates the establishment Risk 1 to 3

Needs

Parse

  • Violations need regex parsing out of free text
  • No per-violation severity at all
  • ZIP codes arrive as floats

Dallas

Wide

Dallas Code Compliance Services

Violations arrive as

Up to 25 numbered blocks spread across dozens of columns

Severity

Assigns numeric point deductions

Needs

Unpivot

  • Coordinates nested inside a lat_long object
  • Violation blocks thin out sharply after the first few
  • Numbered blocks must be unpivoted to a long shape

Two cities publish restaurant inspections, and neither publishes them the same way. Chicago packs every violation into one delimited string; Dallas spreads them across 25 numbered columns, and nothing about reading one helps you read the other. They do not even measure danger at the same level: Chicago grades the establishment, Dallas assigns points. Every design choice below follows from that.

Architecture

Two lanes, one join
Food inspection Medallion architecture: Chicago (long) and Dallas (wide) inspection feeds land unchanged in a Bronze layer on Azure Data Lake, are cleansed and reshaped per city in Databricks PySpark into a Silver layer, unified at violation grain, then modelled in a Snowflake Gold layer as a star schema and served through Tableau.

Profiling

What it changed
Profiling findings and the action each one led to
FoundDetailAction
Dallas violation block sparsity92% populated at block 1, 13% at block 10, under 1% from block 17Unpivot only blocks that carry data, per row
Chicago violation stringsPipe-separated free text, several violations per inspectionRegex parse into code, description, comment
ZIP codesStored as floats, arriving as 60614.0Cast, strip non-digits, zero-pad to five

Profiling ran before any transformation was written, which is the only reason the Dallas unpivot is selective. Melting all 25 blocks would have multiplied row count for columns that are over 99% empty.

Six stages

Decisions, not descriptions

Arrow keys to step

Stage 01of 06

Ingest

Azure Data Factory

  • Both cities landed unchanged
  • Azure Data Lake Gen2 as the raw store
  • Pipeline control and scheduling in ADF

Decision

Chose
Land each city in its own native shape
Over
  • Conform to a shared schema on ingest

Because

  • Conforming on ingest destroys the evidence when a parse is wrong
  • The two shapes need different logic, and that belongs downstream
  • Re-processing never re-downloads

Cost

Two divergent shapes to carry until the silver layer.

Bronze
layer

Governance

Layers and lineage

Why three layers

  • Clear separation of concerns
  • Reprocessing without data loss
  • Scalable to more cities or years
  • Audit-friendly and production-ready

Bronze is never rewritten, so a wrong regex costs a rerun rather than a re-download and a lost original.

Stamped on every record

job_id
Unique pipeline execution that produced the row
load_dt
Ingestion timestamp
source
Which city the record came from

Three columns are the difference between rerunning a job and opening an investigation into which one produced a bad row.

Stack

Everything used

Orchestration

  • Azure Data Factory
  • Azure Data Lake Gen2

Processing

  • Databricks
  • PySpark
  • Regex parsing

Warehouse

  • Snowflake
  • Dynamic Tables
  • Incremental refresh

Modelling

  • ER Studio
  • Star schema
  • Medallion architecture

Profiling

  • Alteryx
  • ydata-profiling
  • Excel

Serving

  • Tableau
See these across every project