DEV Community

Cover image for My First End-to-End Data Pipeline in Databricks
Shrestha Pandey
Shrestha Pandey

Posted on

My First End-to-End Data Pipeline in Databricks

Whenever I searched for resources on Databricks, I found two extremes. Some explained the concepts without showing how they fit together, while others jumped straight into large projects assuming you already knew the basics, but I wanted something in the middle.

Rather than learning every feature separately, I decided to build a small end-to-end project that covered the fundamentals of data engineering in Databricks. I wanted to understand how data moves through the platform, how different components connect, and why concepts like Delta Lake and the Medallion Architecture are used so often.

For this project, I used three simple retail datasets containing customers, products, and orders. Starting with these CSV files, I built a pipeline that reads the data using PySpark, stores it in Delta Lake, organizes it into Bronze, Silver, and Gold layers, analyzes it with Spark SQL, creates a dashboard, and finally automates the entire workflow using Databricks Jobs.

If you're just getting started with Databricks, this project covers many of the concepts you'll use in real-world workflows while keeping the implementation simple enough to follow.

Why Databricks?

Before starting with code, I explored the Databricks workspace to understand what the platform offers. The interesting part was how everything required for a data engineering workflow is available in one place.

The Workspace is where notebooks live, the Catalog helps organize data assets, the SQL Editor is used for writing analytical queries, and Jobs allows notebooks to run automatically on a schedule. Having these components integrated into a single platform makes it much easier to move from raw data to analytics without switching between multiple tools.

Another concept that appears everywhere in Databricks is the Lakehouse Architecture. Raw data needs to be stored safely, transformed into cleaner datasets, and eventually prepared for reporting or dashboards. The Lakehouse approach supports all these stages while using Delta Lake as the storage layer, which brings features like reliable transactions and version history.

This project follows that same approach from start to finish, which makes it easier to understand why the Lakehouse architecture has become a common choice for modern data engineering.

Setting Up the Environment

For development, I used a Databricks Notebook and uploaded my datasets into a Databricks Volume. I used Python and PySpark for data ingestion and transformations, switched to SQL for analysis, and added Markdown cells to organize different sections of the notebook.

The datasets were uploaded into a Databricks Volume, making them easy to access from the notebook.

The project uses three CSV files:

  • customers.csv
  • orders.csv
  • products.csv

Keeping the dataset small made it much easier to focus on understanding the workflow rather than spending time cleaning complex data.

Databricks Volume containing the uploaded CSV files

Building the Data Pipeline with PySpark

With the environment ready, the next step was reading the datasets into Databricks using PySpark. Since the files were already uploaded to a Volume, accessing them from the notebook was simple.

customers = spark.read.csv(
    "/Volumes/workspace/default/retail_data/customers.csv",
    header=True,
    inferSchema=True
)

orders = spark.read.csv(
    "/Volumes/workspace/default/retail_data/orders.csv",
    header=True,
    inferSchema=True
)

products = spark.read.csv(
    "/Volumes/workspace/default/retail_data/products.csv",
    header=True,
    inferSchema=True
)
Enter fullscreen mode Exit fullscreen mode

PySpark automatically inferred the schema, so I didn't have to manually define the data types for every column. After loading each dataset, I used display() to verify that everything had been imported correctly before moving on to transformations.

Storing the Raw Data with Delta Lake

Once the CSV files were loaded, I converted them into Delta tables. This was the beginning of the Bronze layer in the Medallion Architecture.

customers.write.mode("overwrite").format("delta").saveAsTable("bronze_customers")

orders.write.mode("overwrite").format("delta").saveAsTable("bronze_orders")

products.write.mode("overwrite").format("delta").saveAsTable("bronze_products")
Enter fullscreen mode Exit fullscreen mode

The Bronze layer stores the data exactly as it arrives. At this stage, no cleaning or transformations are applied because it's useful to preserve the original data for auditing, debugging, or reprocessing later.

Cleaning the Data in the Silver Layer

To create the Silver layer, I performed some simple transformations on the orders dataset. For this, I removed duplicate records and filled missing values.

silver_orders = (
    bronze_orders
    .dropDuplicates()
    .na.fill({"quantity": 1})
)
Enter fullscreen mode Exit fullscreen mode

The cleaned dataset was then stored as another Delta table. This stage represents a common pattern in data engineering. Cleaning and validating data before using it for analysis helps improve the reliability of downstream reports and dashboards.

Creating the Gold Layer

The final step in the transformation process was creating a dataset that could be used directly for analysis. I joined the customer, product, and order tables into a single DataFrame and calculated the revenue for each order.

from pyspark.sql.functions import col

gold_sales = (
    silver_orders
    .join(bronze_customers, "customer_id")
    .join(bronze_products, "product_id")
    .withColumn("revenue", col("price") * col("quantity"))
)
Enter fullscreen mode Exit fullscreen mode

Finally, I saved the result as a Delta table.

gold_sales.write.mode("overwrite") \
    .format("delta") \
    .saveAsTable("gold_sales")
Enter fullscreen mode Exit fullscreen mode

At this point, raw CSV files gradually turned into a structured dataset that could answer business questions with just a few SQL queries. It also demonstrated how PySpark and Delta Lake work together. PySpark handled the transformations, while Delta Lake provided a reliable storage layer for every stage of the pipeline.

Querying the Data with Spark SQL

Once the Gold table got ready, I switched to SQL to explore the data. It was really feasible to move between PySpark and SQL. Transforming data with PySpark felt simpler, while SQL made it simple to answer business questions without writing additional Python code.

For this project, I used the Databricks SQL Editor and a SQL Warehouse to run analytical queries. SQL Warehouses are optimized for interactive queries and reporting workloads, making them a good choice when exploring datasets or building dashboards.

I started with: Which products generated the highest revenue?

SELECT
product_name,
SUM(revenue) AS total_revenue
FROM gold_sales
GROUP BY product_name
ORDER BY total_revenue DESC;
Enter fullscreen mode Exit fullscreen mode

The result highlighted the products contributing the most revenue.

SQL query and its output in the SQL Editor

Creating a Dashboard

After running the query, I created a simple bar chart directly within Databricks. The dashboard visualized revenue by product, making the results much easier to interpret than reading rows in a table.

Databricks lets you create charts from SQL query results in just a few clicks, which is useful for quickly sharing insights with teammates or stakeholders.

Dashboard showing total revenue by product

Automating the Pipeline with Databricks Jobs

Running a notebook manually is useful during development, though production pipelines usually need to execute on a schedule.

To complete the workflow, I created a Databricks Job for my notebook. The setup involved selecting the notebook, attaching the compute resource, and defining a schedule. Databricks also provides options for retries and notifications, making it easier to monitor automated workloads as projects become more complex.

Databricks Job configuration

Exploring Delta Time Travel

One feature I wanted to try before finishing the project was Delta Time Travel. Every change made to a Delta table is recorded, allowing previous versions to be inspected whenever required.

I viewed the history of my Gold table using:

DESCRIBE HISTORY gold_sales;
Enter fullscreen mode Exit fullscreen mode

This feature can be especially useful when debugging pipelines or recovering from accidental updates.

A Quick Look at Unity Catalog

Since all my tables were created inside Databricks, I also explored Unity Catalog, which serves as the central place for managing data assets. It organizes tables, volumes, and other resources, making them easier to discover and manage across projects.

While this project focused on the fundamentals, Unity Catalog also supports governance features such as permissions and data lineage, which become increasingly important in collaborative environments.

Unity Catalog showing the Bronze, Silver, and Gold tables

What I Learned

Starting with raw CSV files and gradually moving through Bronze, Silver, and Gold layers showed how data evolves before reaching analysts or dashboards. PySpark handled the transformations, Delta Lake provided a reliable storage layer, SQL made analysis simpler, and Databricks Jobs completed the workflow by automating the notebook.

The project is small, but it covers many of the core ideas you'll encounter while working with Databricks. It helped me understand why these concepts exist rather than simply memorizing their definitions.

If you're getting started with Databricks, I'd recommend building a similar end-to-end project. It doesn't require a large dataset, and you'll come away with a much clearer understanding of how the platform works.

GitHub Repository

The complete notebook, datasets, and project files are available here:

🔗 GitHub: Databricks-pipeline

If you build on top of this project or have suggestions for improving the pipeline, I'd love to hear your thoughts.

For more such project ideas, visit:
https://vickybytes.com

Top comments (0)