Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

17 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

πŸš€ Azure Data Factory End-to-End Project

An end-to-end Azure Data Factory (ADF) project demonstrating real-world data engineering patterns β€” REST API ingestion, on-premises file ingestion, incremental loading, watermark management, orchestration, alerting, audit logging, and REST API pagination.


πŸ“š Medium Blog Series β€” Incremental Data Loading

I've documented the incremental loading concepts and implementation behind this project in a 4-part Medium series. Click a button below to jump straight to the article.

πŸ’‘ For the incremental pipelines in this repository, start with Part 1 and follow the series sequentially.


πŸ—οΈ Project Overview

This project contains 7 Azure Data Factory pipelines, each covering a common real-world data engineering scenario.

# Pipeline Key Concept
1 pl_API_Ingestion REST API β†’ ADLS Gen2
2 pl_OnPremFiles_To_AzureBlobBronze On-Prem Files β†’ ADLS Gen2
3 pl_SQLtoAzure_Incremental_Json Incremental Load + JSON Watermark
4 pl_dailydata_load_with_alerts Orchestration + Logic App Alerts
5 pl_onPremSQl_To_AzureSQL_Incremental_WatermarkTable Multi-Table Incremental Load
6 pl_onPremSQl_To_AzureSQL_Incremental_WatermarkTable_ScriptActivity Incremental Load + Audit Logging
7 pl_paginationExample REST API Pagination

πŸ”Ή Pipeline 1 β€” API Ingestion

pl_API_Ingestion

Pulls DimAirport.json from GitHub Raw content into the ADLS Gen2 Bronze layer.

GitHub Raw β†’ Copy API Data β†’ ADLS Gen2 Bronze
  • Source: ds_APISource β†’ ls_githubAPI_source β†’ HttpServer / Anonymous β†’ DimAirport.json
  • Sink: ds_github_sink β†’ ls_bronze β†’ ADLS Gen2 β†’ bronze/github/DimAirport.json
  • Key Settings: JsonSource with HttpReadSettings, HTTP GET, JsonSink with AzureBlobFSWriteSettings, retry = 2, retryIntervalInSeconds = 30, enableStaging = false

πŸ”Ή Pipeline 2 β€” On-Premises Files to ADLS Bronze

pl_OnPremFiles_To_AzureBlobBronze

Migrates 3 CSV files in parallel from an on-premises Windows file server to ADLS Gen2 Bronze: DimAirline.csv, DimFlight.csv, DimPassenger.csv.

On-Prem Windows File Server β†’ ForEach (Parallel) β†’ Copy Activity β†’ ADLS Gen2 Bronze
  • Pipeline Parameter: file_name β€” e.g. [{"fileName": "DimAirline.csv"}, {"fileName": "DimFlight.csv"}, {"fileName": "DimPassenger.csv"}]
  • Key Expressions: @pipeline().parameters.file_name, @item().fileName, @dataset().p_fileName_source, @dataset().p_fileName_sink
  • Source: ds_OnPremSource β†’ ls_onPrem_Files β†’ FileServer / IROnPremise β†’ E:\OnPremiseFiles\{fileName}
  • Sink: ds_onPremSink β†’ ls_bronze β†’ ADLS Gen2 β†’ bronze/OnPremDataFiles/{fileName}

πŸ”Ή Pipeline 3 β€” Incremental Load Using JSON Watermark

pl_SQLtoAzure_Incremental_Json

Performs an incremental load from Azure SQL FactBookings to ADLS Gen2 in Parquet format, using a JSON file as the watermark store.

LastLoad Lookup ─┐
                  β”œβ”€β†’ Copy SQL Data β†’ Parquet
LatestLoad Lookup β”˜
                        ↓
                 Update Watermark
  • Last Load: reads lastload.json from Azure Blob to get the last processed booking_date
  • Latest Load: SELECT MAX(booking_date) AS LatestLoad FROM dbo.FactBookings;
  • Incremental Query:
    SELECT * FROM dbo.FactBookings
    WHERE booking_date > '@{activity('LastLoad').output.firstRow.lastload}'
    AND booking_date <= '@{activity('LatestLoad').output.firstRow.LatestLoad}';
  • Sink: Azure SQL β†’ Copy Activity β†’ ADLS Gen2 β†’ Bronze/sql/ β†’ Parquet + Snappy compression
  • Watermark Update: the latest watermark is written back to lastload.json

πŸ“– Detailed explanation in Part 1 of the Medium series above.


πŸ”Ή Pipeline 4 β€” Daily Orchestration & Alerts

pl_dailydata_load_with_alerts

Orchestrator pipeline that calls the incremental pipeline and reports execution status to an Azure Logic App.

DailyDataLoad β†’ Execute Pipeline β†’ pl_SQLtoAzure_Incremental_Json β†’ Call Logic App
  • Execute Pipeline: calls pl_SQLtoAzure_Incremental_Json with waitOnCompletion = true
  • Logic App Trigger: fires on both βœ… Success and ❌ Failure
  • Payload:
    {
      "pipeline_name": "@{pipeline().Pipeline}",
      "run_id": "@{pipeline().RunId}",
      "status": "@{activity('DailyDataLoad').Status}",
      "error": "@{if(equals(activity('DailyDataLoad').Status,'Failed'), string(activity('DailyDataLoad').error), 'No Error')}"
    }

πŸ”Ή Pipeline 5 β€” Multi-Table Incremental Load

pl_onPremSQl_To_AzureSQL_Incremental_WatermarkTable

Multi-table incremental loading from On-Premises SQL Server to Azure SQL using a centralized watermark table, for dbo.iplteams and dbo.salesitems, both keyed on a last_updated watermark column.

ForEach Table
     ↓
Old Watermark ─┐
               β”œβ†’ If Condition ─→ TRUE β†’ Copy β†’ Update Watermark
New Watermark β”€β”˜                β†’ FALSE β†’ Skip
  • Old Watermark: SELECT WatermarkValue FROM watermarktable WHERE TableName = '@{item().TableName}';
  • New Watermark: SELECT MAX(last_updated) AS NewWatermarkValue FROM @{item().TableName};
  • If Condition: @greater(activity('New_LookUp_Col').output.firstRow.NewWatermarkValue, activity('Old_LookUp_Col').output.firstRow.WatermarkValue)
  • Dynamic SQL built from table schema, table name, watermark column, old and new watermark values
  • Sink: AzureSqlSink, writeBehavior = upsert, useTempDB = true, keys = [id]
  • Watermark Update: stored procedure [dbo].[usp_write_watermark] with parameters last_updated, tableName

πŸ“– Detailed explanation in the Medium series above.


πŸ”Ή Pipeline 6 β€” Incremental Load + Audit Logging

pl_onPremSQl_To_AzureSQL_Incremental_WatermarkTable_ScriptActivity

An enhanced version of Pipeline 5 adding execution timing, a Script Activity for watermark updates, success/failure audit logging, rows-copied tracking, and error tracking.

Set Start Time β†’ Old Watermark Lookup β†’ New Watermark Lookup β†’ If Condition
                                                                     ↓
                                                          Copy β†’ Success/Failed β†’ Audit
  • Set Start Time: PipelineStartTime = @utcNow()
  • Script Activity β€” Update Watermark:
    UPDATE dbo.watermarktable
    SET WatermarkValue = @last_updated
    WHERE TableName = @tableName;
  • Success/Failure Audit writes to dbo.PipelineAudit: PipelineName, TableName, SourceName, TargetName, WatermarkOld, WatermarkNew, RowsCopied, Status, ErrorMessage, StartTime, EndTime
  • Key Expressions: @pipeline().Pipeline, @item().TableName, @activity('Copy_FromOnPremSQL_ToAzureSQL').output.rowsCopied, @activity('Copy_FromOnPremSQL_ToAzureSQL').error.message, @variables('PipelineStartTime'), @utcNow()
  • Evolution from Pipeline 5: the old SP_Update_WaterMark activity is now inactive β€” watermark updates are handled by the Script Activity instead

πŸ“– Detailed explanation in the Medium series above.


πŸ”Ή Pipeline 7 β€” REST API Pagination

pl_paginationExample

Ingests PokΓ©mon data from the PokΓ©API across multiple pages using ADF's native RANGE pagination.

PokΓ©API β†’ Web Activity β†’ Get Total Count β†’ Copy Activity β†’ RANGE Pagination β†’ ADLS Gen2 Bronze
  • Initial Request: https://pokeapi.co/api/v2/pokemon?limit=20&offset=0
  • Pagination Rule: QueryParameters.offset = RANGE:0:@{activity('Get API Data').output.count}:20 β†’ generates offset=0, 20, 40, ... 1300
  • Sink: ds_API_Target_JSON β†’ ADLS Gen2 β†’ bronze/PaginationExample/

🎯 Key ADF Concepts Demonstrated

REST API ingestion Β· ADLS Gen2 Β· On-Premises File Server Β· Self-hosted Integration Runtime Β· ForEach activity Β· Parallel processing Β· Pipeline parameters Β· Dataset parameters Β· Dynamic expressions Β· Incremental loading Β· JSON watermark Β· Watermark table Β· Azure SQL Upsert Β· Execute Pipeline Β· Web Activity Β· Logic App integration Β· Script Activity Β· Audit logging Β· Error handling Β· REST API pagination Β· RANGE pagination


πŸ“š Medium Articles





πŸ’Ό Interview Summary

I built multiple Azure Data Factory pipelines covering real-world data engineering scenarios β€” REST API ingestion, parallel on-premises file migration, watermark-based incremental loading, multi-table processing using ForEach, Azure SQL upserts, Logic App alerts, Script Activity-based watermark management, audit logging, and REST API pagination.


πŸ”— Repository

github.com/Prabhas92/ADFProject

πŸ‘¨β€πŸ’» Author

Chethan Prabhas

Azure Data Factory β€’ SQL β€’ Azure β€’ Python β€’ Data Engineering

About

Azure Data Factory end-to-end project demonstrating real-world data engineering workflows including API ingestion, on-premises data migration, incremental loading with watermarking, pipeline orchestration, Logic App alerts, audit logging, and REST API pagination.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors