Skip to content

Bronze Layer Ingestion

The Bronze Layer is responsible for raw data replication. It ingests source CSV datasets deposited in a Databricks Unity Catalog Volume and saves them as raw Delta tables.

Objectives

  • Raw Replica: Retain original schemas and column names without structural transformation.
  • Traceability: Append metadata (like _load_timestamp) to keep track of ingestion history.
  • Delta Storage: Store as Delta Lake format to benefit from ACID transactions, version history, and optimization properties.

Ingestion Pipeline (01_ingest.py)

The script loops through a mapping of CSV filenames → table names, reading each file with schema inference and writing it as a Delta table.

python
# Databricks notebook source
# Import Required Packages
from pyspark.sql import SparkSession
from pyspark.sql.functions import current_timestamp

# Initialize Spark session for local IDEs (Databricks will just use its existing session)
spark = SparkSession.builder \
    .appName("RetailIntelligence_Bronze") \
    .getOrCreate()

# Set Base Path For Unity Catalog Volume
volume_path = "/Volumes/raw_data/default/raw_data/"

# Map the CSV file names to your new Bronze table names
tables_to_ingest = {
    "olist_orders_dataset.csv": "bronze_olist_orders",
    "olist_order_items_dataset.csv": "bronze_olist_order_items",
    "olist_customers_dataset.csv": "bronze_olist_customers",
    "olist_products_dataset.csv": "bronze_olist_products",
    "product_category_name_translation.csv": "bronze_category_translation"
}

for file_name, table_name in tables_to_ingest.items():
    print(f"Ingesting {file_name} -> raw_data.bronze.{table_name}...")
    
    # 1. Read raw CSV with schema inference
    df = (spark.read
          .format("csv")
          .option("header", "true")
          .option("inferSchema", "true")
          .load(volume_path + file_name))
        
    # 2. Append standard audit column
    df_bronze = df.withColumn("_load_timestamp", current_timestamp())
    
    # 3. Write out as a Delta table
    (df_bronze.write
     .format("delta")
     .mode("overwrite")
     .option("mergeSchema", "true")
     .saveAsTable(f"raw_data.bronze.{table_name}"))
        
print("Bronze layer ingestion complete!")

# Verification query
spark.sql("SHOW TABLES IN raw_data.bronze").show()

Code Deepdive

StepCodePurpose
Volume path"/Volumes/raw_data/default/raw_data/"References a Unity Catalog Volume — a secure, governed file store separate from the database namespace.
Table mapping{"olist_orders_dataset.csv": "bronze_olist_orders", ...}Decouples source filenames from target table names. Adding a new CSV only requires a new dictionary entry.
Schema inference.option("inferSchema", "true")Spark reads a sample of each CSV and automatically determines column types (int, string, double, etc.).
Audit column.withColumn("_load_timestamp", current_timestamp())Stamps every row with the exact time it was ingested, enabling time-based debugging and lineage tracking.
Merge schema.option("mergeSchema", "true")If the upstream CSV adds a new column, Delta Lake will evolve the table schema instead of failing.
Overwrite mode.mode("overwrite")Full-refresh on each run. Historical versions are still accessible via Delta Lake Time Travel.

NOTE

Overwrite mode is used intentionally at the Bronze layer — it prevents double-counting raw items across pipeline runs. If you need to audit what changed between runs, use Delta Lake's DESCRIBE HISTORY command.


Source Datasets

The following Olist Brazilian E-Commerce CSV files are ingested:

CSV FileBronze TableRow Description
olist_orders_dataset.csvbronze_olist_ordersOne row per order (order ID, customer ID, timestamps).
olist_order_items_dataset.csvbronze_olist_order_itemsOne row per order line item (product, price, freight).
olist_customers_dataset.csvbronze_olist_customersOne row per customer (ID, city, state, zip).
olist_products_dataset.csvbronze_olist_productsOne row per product (category, dimensions, weight).
product_category_name_translation.csvbronze_category_translationPortuguese → English category name mapping.

Retail Intelligence Platform Documentation. Built with VitePress.