Logo Lanfrica
  • Accueil
  • Atlas
  • Analyses
  • Documentation
  • Sign in

© 2026 Lanfrica. Tous droits réservés. Tous les droits d'auteur des ressources affichées sur le site Web Lanfrica appartiennent aux détenteurs de droits d'auteur d'origine, sauf indication contraire explicite.

Njokimary/kenya-food-prices-pipeline

Domaine:

agriculturesocioeconomic

Type de record:

software
Créateur:
Njo
Hôte:
End-to-end data pipeline for Kenyan food prices - PostgreSQL, Airflow, dbt, Metabase # Kenya Food Prices Pipeline End-to-end Medallion-style data pipeline for Kenyan food prices (WFP dataset, 2006–2025). **Stack:** PostgreSQL · Python (pandas, SQLAlchemy) · Apache Airflow · dbt Core · Metabase/Grafana ## Phase 1 — Bronze / Staging Layer - `sql/01_create_staging.sql` — staging table `raw_food_prices` with a 6-column natural-key unique index. Prices use `NUMERIC`, never `FLOAT`, to avoid precision drift in financial aggregation. - `src/load_raw.py` — incremental loader (pandas + SQLAlchemy). Uses `ON CONFLICT DO NOTHING` against the natural key, so re-runs and monthly re-downloads insert only the delta. Verified: run 1 inserts 26,745 rows; run 2 inserts 0. - `sql/02_validation_queries.sql` — required analytical checks (filtering, aggregation, quality density, temporal extraction). ## Data Quality Issues Observed (Bronze) **1. Missing geographic metadata.** 68 rows have NULL `admin1`, `admin2`, `latitude`, and `longitude` — all for the market "Hola (Tana River)". The county is recoverable from the market name; the Silver layer will backfill it. **2. Mixed units make raw prices non-comparable.** The same commodity is quoted in KG, 90 KG, 50 KG, 64 KG, and 126 KG bags. Averaging raw `price` across units is meaningless — the Silver layer must derive `price_per_kg`. **3. Inconsistent commodity granularity.** Maize appears as five variants ("Maize", "Maize (white)", "Maize (white, dry)", "Maize flour", "Maize flour (white)"). Trend analysis needs a standardised commodity dimension. **4. Mixed observation types in one column.** `priceflag` holds "actual" (17,861), "aggregate" (8,651), and the combined value "actual,aggregate" (233). Aggregates must not blend with actual observations in analytics. **5. Dates are monthly snapshots disguised as days.** Every record is stamped on the 15th of the month. The data is monthly, not daily — `dim_date` will model it at month grain. ## Setup ``` python3 -m venv venv && source venv/bin/activate pip install pan …

Visit

github.com