A hands-on learning project that accepts IBM DB2 SQL statements and generates equivalent Apache Spark SQL and PySpark DataFrame code โ complete with query analysis, complexity scoring, data lineage, and optimization recommendations.
| Concept | What You Learn |
|---|---|
| DB2 Architecture | Tables, indexes, packages, plans, tablespaces, buffer pools |
| SQL Parsing | How text becomes an AST (Abstract Syntax Tree) |
| Dialect Translation | Why DB2 SQL differs from Spark SQL and how to convert |
| PySpark DataFrame API | How SQL maps to transformation chains |
| Query Optimization | Broadcast joins, partitioning, predicate pushdown |
| Data Lineage | Tracking data flow from source to output |
| Migration Patterns | How organizations move DB2 workloads to Spark |
db2-spark-modernizer/
โโโ src/
โ โโโ ast/ # AST node definitions
โ โ โโโ nodes.py # SelectNode, TableNode, JoinNode, etc.
โ โโโ parser/ # SQL Parser
โ โ โโโ sql_parser.py # DB2SQLParser (sqlglot-backed)
โ โโโ analyzer/ # Query Analysis
โ โ โโโ query_analyzer.py # Metadata extraction
โ โ โโโ complexity_analyzer.py # 1-10 complexity scoring
โ โโโ spark_sql_generator/ # Spark SQL Generation
โ โ โโโ generator.py # sqlglot dialect transpilation
โ โโโ dataframe_generator/ # PySpark Code Generation
โ โ โโโ generator.py # DataFrame API code synthesis
โ โโโ lineage/ # Data Lineage
โ โ โโโ lineage_engine.py # DAG + Mermaid diagram
โ โโโ optimization/ # Spark Optimization
โ โ โโโ optimizer.py # Recommendations engine
โ โโโ docs_generator/ # Migration Documentation
โ โโโ generator.py # Auto-generated migration docs
โโโ ui/
โ โโโ app.py # Streamlit application
โโโ examples/
โ โโโ scenarios.py # 12 real-world migration scenarios
โโโ tests/
โ โโโ test_parser.py # 30 parser tests
โ โโโ test_analyzer.py # 22 analyzer tests
โ โโโ test_spark_generator.py # 39 generator + lineage tests
โโโ docs/
โ โโโ mapping_catalog.md # DB2 โ Spark concept mapping
โโโ requirements.txt
โโโ README.md
pip install -r requirements.txtrequirements.txt:
sqlglot>=25.0.0
streamlit>=1.35.0
graphviz>=0.20
pytest>=8.0.0
pandas>=2.0.0
streamlit run ui/app.pyOpen http://localhost:8501 in your browser.
pytest tests/ -v
# 91 tests, all passingfrom src.parser.sql_parser import parse_db2_sql
from src.analyzer.query_analyzer import analyze_query
from src.analyzer.complexity_analyzer import analyze_complexity
from src.spark_sql_generator.generator import generate_spark_sql
from src.dataframe_generator.generator import generate_pyspark_code
db2_sql = """
SELECT C.CUSTOMER_ID,
C.CUSTOMER_NAME,
SUM(T.AMOUNT) AS TOTAL_AMOUNT
FROM BANKDB.CUSTOMER C
INNER JOIN BANKDB.TRANSACTION T ON C.CUSTOMER_ID = T.CUSTOMER_ID
WHERE C.STATUS = 'ACTIVE'
GROUP BY C.CUSTOMER_ID, C.CUSTOMER_NAME
HAVING SUM(T.AMOUNT) > 10000
ORDER BY TOTAL_AMOUNT DESC
FETCH FIRST 100 ROWS ONLY
"""
# Parse
result = parse_db2_sql(db2_sql)
# Analyze
metadata = analyze_query(result)
complexity = analyze_complexity(result, metadata)
# Generate
spark_sql = generate_spark_sql(db2_sql)
pyspark = generate_pyspark_code(result)
print(spark_sql.spark_sql)
print(pyspark.code)
print(f"Complexity: {complexity.score}/10 ({complexity.level})")The UI has 8 tabs for each migration artifact:
| Tab | Content |
|---|---|
| ๐ Parsed AST | Visual tree of query nodes |
| ๐ Metadata | Tables, columns, filters, features |
| โก Spark SQL | Side-by-side DB2 vs Spark SQL |
| ๐ PySpark Code | DataFrame transformation chain |
| ๐ Complexity | Score (1-10), factors, challenges |
| ๐ Lineage | Data flow graph + Mermaid diagram |
| ๐ Optimizations | Ranked recommendations |
| ๐ Migration Doc | Auto-generated migration document |
Sidebar features:
- Load 12 pre-built industry examples (Banking, Insurance, Retail, Telecom, Healthcare)
- Toggle AST JSON view
- Toggle DB2 concept explanations
- Download migration documents (.md)
| Feature | Status | Notes |
|---|---|---|
SELECT columns, aliases |
โ | Including AS aliases |
SELECT * |
โ | |
SELECT DISTINCT |
โ | |
FROM with schema qualification |
โ | SCHEMA.TABLE |
| Table aliases | โ | |
INNER JOIN |
โ | |
LEFT JOIN |
โ | |
RIGHT JOIN |
โ | |
FULL OUTER JOIN |
โ | |
CROSS JOIN |
โ | |
WHERE with AND/OR |
โ | |
IN, BETWEEN, LIKE |
โ | |
GROUP BY |
โ | |
HAVING |
โ | |
ORDER BY ASC/DESC |
โ | |
COUNT, SUM, AVG, MIN, MAX |
โ | |
UNION / UNION ALL |
โ | |
FETCH FIRST n ROWS ONLY |
โ | โ LIMIT n |
CURRENT DATE / CURRENT TIMESTAMP |
โ | DB2 special registers |
WITH UR/CS/RS/RR isolation hints |
โ | Removed with warning |
| Subqueries | Basic support | |
CASE expressions |
Parsed, basic codegen | |
Window functions (OVER) |
Detected, flagged | |
| Stored procedures | โ | Documentation only |
12 pre-built examples across 5 industries:
bank_001โ Customer Balance Lookup (Simple)bank_002โ Daily Transaction Summary (Medium)bank_003โ Customer Account Portfolio Analysis (Medium)bank_004โ Risk Portfolio Summary (Complex)bank_005โ UNION ALL Account Report (Medium)
ins_001โ Active Policy Report by Agent (Medium)ins_002โ Claims Loss Ratio Analysis (Complex)
ret_001โ Product Sales Analysis (Medium)ret_002โ Low Inventory Alert (Medium)
tel_001โ Subscriber Usage for Billing (Medium)
hc_001โ Patient Billing Summary (Complex)
cobol_001โ Embedded SQL Extraction Example
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ z/OS Mainframe โ
โ โโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโ โ
โ โ CICS/IMS โ โ DB2 Subsystem โ โ
โ โ (Online TP) โโโถโ โโโโโโโโโโโโโ โ โ
โ โโโโโโโโโโโโโโโโ โ โ Optimizer โ โ โ
โ โโโโโโโโโโโโโโโโ โ โ Buffer โ โ โ
โ โ Batch JCL โโโถโ โ Pools โ โ โ
โ โโโโโโโโโโโโโโโโ โ โโโโโโโโโโโโโ โ โ
โ โ Tablespaces โ โ
โ โโโโโโโโโโโโโโโโโโโ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โฌ Migration
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Apache Spark / Delta Lake โ
โ Driver โ Catalyst Optimizer โ
โ โโโโโโโโ โโโโโโโโ โโโโโโโโ โโโโโโโโ โ
โ โExec 1โ โExec 2โ โExec 3โ โExec 4โ โ
โ โโโโโโโโ โโโโโโโโ โโโโโโโโ โโโโโโโโ โ
โ Delta Lake (cloud storage) โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
DB2 SQL Text
โ Lexer (sqlglot)
Tokens: [SELECT, CUSTOMER_ID, FROM, CUSTOMER, WHERE, ...]
โ Parser
sqlglot AST (internal representation)
โ Our converter
Educational AST nodes:
SelectNode
โโโ TableNode(CUSTOMER)
โโโ ColumnNode(CUSTOMER_ID)
โโโ WhereNode(BALANCE > 1000)
โโโ OrderByNode(CUSTOMER_ID ASC)
| DB2 Concept | Spark Equivalent |
|---|---|
| Table | DataFrame / Delta Lake Table |
| View | Temp View / DataFrame |
| Index | Partitioning + Z-ORDER |
| Tablespace | Database / Schema |
| Buffer Pool | Spark Memory Cache |
| Package/Plan | Catalyst Physical Plan |
| RUNSTATS | ANALYZE TABLE (Delta) |
| Stored Procedure | Spark UDF / Python Function |
| Cursor | DataFrame iterator / collect() |
| COMMIT/ROLLBACK | Delta Lake ACID Transactions |
| FETCH FIRST n ROWS | LIMIT n |
| JCL Batch Job | Spark Job / Databricks Job |
Simple SELECT:
-- DB2
SELECT CUSTOMER_ID, NAME, BALANCE
FROM BANKDB.CUSTOMER
WHERE STATUS = 'ACTIVE'
ORDER BY NAME
-- Spark SQL (identical โ ANSI SQL)
SELECT CUSTOMER_ID, NAME, BALANCE
FROM BANKDB.CUSTOMER
WHERE STATUS = 'ACTIVE'
ORDER BY NAME
-- PySpark DataFrame API
customer_df = spark.table("BANKDB.CUSTOMER")
customer_df = customer_df.filter(col("STATUS") == "ACTIVE")
customer_df = customer_df.select("CUSTOMER_ID", "NAME", "BALANCE")
customer_df = customer_df.orderBy(col("NAME").asc())DB2-Specific Syntax:
-- DB2: FETCH FIRST
SELECT * FROM CUSTOMER FETCH FIRST 100 ROWS ONLY
-- Spark SQL
SELECT * FROM CUSTOMER LIMIT 100
-- PySpark
customer_df.limit(100)-- DB2: CURRENT DATE (special register)
WHERE TXN_DATE = CURRENT DATE
-- Spark SQL
WHERE TXN_DATE = CURRENT_DATE()
-- PySpark
.filter(col("TXN_DATE") == current_date())| Score | Level | Migration Effort | Auto-Migration |
|---|---|---|---|
| 1โ3 | ๐ข Simple | Hours | 85โ95% |
| 4โ5 | ๐ก Medium | Days | 65โ85% |
| 6โ7 | ๐ Complex | Weeks | 40โ65% |
| 8โ10 | ๐ด Critical | Months | <40% |
# 1. BROADCAST JOIN (for small dimension tables)
from pyspark.sql.functions import broadcast
result = large_fact.join(broadcast(small_dim), "key")
# 2. PARTITION PUSHDOWN (for large tables)
spark.conf.set("spark.sql.adaptive.enabled", "true")
df = spark.table("fact_table").filter(col("region") == "NORTH")
# 3. AGGREGATE ONCE (all functions in one .agg() call)
result = df.groupBy("region").agg(
sum("amount").alias("total"),
count("id").alias("cnt"),
avg("balance").alias("avg_bal")
)
# 4. SEMI-JOIN (replace IN subquery)
# DB2: WHERE id IN (SELECT id FROM vip_table)
# Spark:
result = df.join(vip_df.select("id"), "id", "left_semi")# All tests
pytest tests/ -v
# With coverage
pytest tests/ -v --cov=src --cov-report=term-missing
# Specific test file
pytest tests/test_parser.py -v
pytest tests/test_analyzer.py -v
pytest tests/test_spark_generator.py -vTest coverage:
test_parser.pyโ 30 tests: SELECT, WHERE, JOIN, UNION, GROUP BY, HAVING, ORDER BY, preprocessingtest_analyzer.pyโ 22 tests: metadata extraction, complexity scoringtest_spark_generator.pyโ 39 tests: Spark SQL gen, PySpark gen, lineage engine
- DB2 SQL Parser (sqlglot-backed)
- Educational AST nodes
- Query metadata extraction
- Complexity scoring (1-10)
- Spark SQL generation (dialect transpilation)
- PySpark DataFrame code generation
- Data lineage graph + Mermaid diagrams
- Spark optimization recommendations
- Migration documentation generator
- Streamlit UI (8 tabs)
- 12 industry scenarios
- 91 pytest unit tests
- Subquery support (full correlated subqueries)
- Common Table Expressions (CTEs / WITH clause)
- Window functions (ROW_NUMBER, RANK, LEAD, LAG)
- Stored procedure analysis
- COBOL embedded SQL extractor
- Delta Lake DDL generation
- Query performance estimator
- AI-generated migration explanations (Claude API)
- SQL dialect comparison dashboard
- Batch migration: analyze a folder of SQL files
In large-scale mainframe modernization projects:
- IBM DataStage / AWS DMS โ extract DB2 data to cloud storage
- Tools like this โ analyze and translate SQL workloads
- Apache Spark / Databricks โ run translated workloads at scale
- Delta Lake โ replace DB2 tables with ACID-compliant lake tables
- Apache Atlas / OpenLineage โ enterprise lineage tracking
This project teaches the analytical and translation phase that sits between extraction and execution.
| Component | Technology |
|---|---|
| SQL Parsing | sqlglot |
| UI | Streamlit |
| Diagrams | Mermaid (text-based) |
| Testing | pytest |
| Data manipulation | pandas |
| Language | Python 3.9+ |
Built as a learning-focused educational tool for DB2 developers moving to Apache Spark and modern data lake architectures.