Apache Airflow: From Basics to Mastery
In this project, you will build an Airflow pipeline that automates the loading of data into a Data Warehouse (such as Amazon Redshift, Google BigQuery, or Snowflake).
The pipeline will:
Extract data from a source (CSV in S3 or GCS).
Transform the data into a clean format.
Load it into a data warehouse table for analytics.
This mimics real-world batch ETL workflows in data engineering.
Learning Objectives
By the end of this project, you will be able to:
Extract data from cloud storage (e.g., S3, GCS).
Transform raw files into structured format.
Load data into a data warehouse using Airflow operators/hooks.
Automate the process on a daily schedule.
Project Requirements
- Apache Airflow running (Docker or Kubernetes).
A data warehouse: choose one → Amazon Redshift, Google BigQuery, or Snowflake.
Cloud storage bucket (e.g., S3 for Redshift, GCS for BigQuery).
Python packages:
pandas,sqlalchemy, and Airflow provider packages.
Project Architecture
ETL Flow:
Extract → Read CSV from S3 (or GCS).
Transform → Clean data with
pandas.Load → Insert into warehouse table.
Graph View:
Extract → Transform → LoadDAG Implementation (Redshift Example with S3)
from airflow import DAG
from airflow.operators.python import PythonOperator
from airflow.providers.amazon.aws.hooks.s3 import S3Hook
from airflow.providers.postgres.hooks.postgres import PostgresHook
import pandas as pd
from io import StringIO
from datetime import datetime
# Step 1: Extract data from S3
def extract_data(**context):
s3 = S3Hook(aws_conn_id="aws_default")
file_obj = s3.read_key(key="raw/sales.csv", bucket_name="my-data-bucket")
context['ti'].xcom_push(key='raw_csv', value=file_obj)
# Step 2: Transform with pandas
def transform_data(**context):
raw_csv = context['ti'].xcom_pull(key='raw_csv', task_ids='extract_task')
df = pd.read_csv(StringIO(raw_csv))
df_clean = df.dropna().rename(columns={"amount": "sales_amount"})
context['ti'].xcom_push(key='clean_data', value=df_clean.to_dict('records'))
# Step 3: Load into Redshift
def load_data(**context):
records = context['ti'].xcom_pull(key='clean_data', task_ids='transform_task')
df = pd.DataFrame(records)
redshift = PostgresHook(postgres_conn_id="redshift_conn")
engine = redshift.get_sqlalchemy_engine()
df.to_sql("sales", engine, if_exists="replace", index=False)
# DAG definition
with DAG(
dag_id="warehouse_load_pipeline",
description="Daily ETL into Redshift",
start_date=datetime(2025, 1, 1),
schedule_interval="@daily",
catchup=False
) as dag:
extract_task = PythonOperator(
task_id="extract_task",
python_callable=extract_data,
provide_context=True
)
transform_task = PythonOperator(
task_id="transform_task",
python_callable=transform_data,
provide_context=True
)
load_task = PythonOperator(
task_id="load_task",
python_callable=load_data,
provide_context=True
)
extract_task >> transform_task >> load_task
Key Notes
Extract → S3Hook retrieves the raw CSV file.
Transform → Clean and normalize data with Pandas.
Load → PostgresHook connects to Redshift and inserts data.
XComs → Share data between steps.
Expected Output
A Redshift table called sales containing cleaned data:
| order_id | customer_id | sales_amount | order_date |
|---|---|---|---|
| 1001 | C101 | 299.99 | 2025-01-01 |
| 1002 | C102 | 159.50 | 2025-01-01 |
Project Extensions (Optional)
Replace Redshift with BigQuery (
BigQueryInsertJobOperator) or Snowflake (Snowflake hook).Add a validation step to check row counts before and after load.
Store transformed data in Parquet instead of loading raw CSV.
Add a Slack notification task after successful load.
Deliverables
warehouse_load_pipeline.pyDAG file in Airflowdags/folder.A populated sales table in your data warehouse.
Screenshots of DAG Graph View and task logs.
Â
Next up: Project 3 – Orchestrate a Machine Learning Workflow
You’ll automate a full ML pipeline, from preprocessing to model training, using Airflow.
Finish Course Early?
You have not completed all required lessons and assessments.