Databricks Jobs → Lakehouse Studio Migration Guide: E-Commerce ETL Pipeline
If your data pipeline runs on Databricks Jobs — multi-task DAGs, task dependencies, scheduled triggers — the core migration effort to Singdata Lakehouse Studio is very low. Task content (PySpark/SQL code) is minimally rewritten with ZettaPark (4 mechanical substitutions). Task orchestration (DAG dependencies, cron scheduling) is rebuilt with a few cz-cli commands, all configured in one pass.
This article validates this with a real e-commerce ETL pipeline: Bronze ingestion → Silver cleansing and joining → Gold aggregation. 3 tasks + DAG dependencies + daily 02:00 schedule, fully migrated to Lakehouse Studio, passing all 8 automated validations.
Full code on GitHub: databricks2lakehouse-jobs
Source Project
01_source/jobs/ecommerce_etl_job.json: Original Databricks Jobs definition — 3 notebook tasks, dependency chain 01→02→03, daily trigger at 02:00 AM:
The pipeline processes e-commerce clickstream: 500 events × 30 products → daily sales summary across 5 categories.
Migrated code is in 03_lakehouse/tasks/, comparable file-by-file with 01_source/notebooks/.
Conclusion First
| Change | Effort | Notes |
|---|---|---|
| Task content (Python code) | Very low | ZettaPark 4 substitutions (import/session/table path/saveAsTable) |
| Task creation | Low | cz-cli task create --type PYTHON --folder <id> |
| Dependencies | Low | --dep-tasks '[{"taskId":N,"taskName":"x"}]' |
| Quartz cron → standard cron | Very low | "0 0 2 * * ?" → "0 2 * * *" |
| Alert notifications | Low | Databricks email → Studio monitoring rules (email/DingTalk/Feishu) |
dbutils.notebook.run(nb), Job cluster configuration — no migration needed, handled automatically by Studio DAG and Virtual Cluster.
Tech Stack Comparison
| Databricks Jobs | Lakehouse Studio | |
|---|---|---|
| Pipeline definition | Job JSON (tasks: [...]) | cz-cli task create/save-config |
| Task dependencies | depends_on: [{task_key}] | --dep-tasks '[{"taskId":N,"taskName":"x"}]' |
| Task content | Databricks Notebook (PySpark) | Studio Python task (ZettaPark) |
| Session | spark (global injection) | clickzetta_dbutils.get_active_lakehouse_engine() |
| Schedule cron | Quartz "0 0 2 * * ?" | Standard "0 2 * * *" |
| Cluster configuration | job_clusters: [{...EC2 config}] | Virtual Cluster auto-managed, no configuration needed |
dbutils.notebook.run(nb) | Chained invocation | Replaced by Studio DAG dependencies |
| Failure alerts | email_notifications.on_failure | Studio monitoring rules (email/DingTalk/Feishu) |
Migration Steps
Step 1: Task Content — ZettaPark 4 Substitutions
Each notebook requires minimal changes; all business logic is preserved:
DataFrame logic (join/filter/groupBy/agg/withColumn) is completely unchanged.
Step 2: Task Creation
Step 3: Set DAG Dependencies
Databricks Jobs uses depends_on: [{task_key}]; Studio uses --dep-tasks (requires both taskId and taskName):
Step 4: Schedule Cron
Databricks uses Quartz 6-field format; Studio uses standard 5-field cron:
Step 5: Deploy
Step 6: Failure Alert Configuration
Databricks configures email_notifications directly in the Job JSON; Studio configures via monitoring rules:
| Databricks | Studio |
|---|---|
Job JSON email_notifications.on_failure | Studio UI: Alert Monitoring → New Monitoring Rule |
| Email only | Supports email, SMS, phone (high severity), Webhook (DingTalk/Feishu) |
| Task-level configuration | Notification policies can be reused across tasks |
Configuration path: Studio UI → Operations Monitoring → Alert Monitoring → New Monitoring Rule → Select "Task Instance Failure" event → Configure notification method (email/DingTalk/Feishu Webhook)
E2E Validation Results
Tested on AWS Singapore instance, 8/8 all passed:
| Check | Expected | Result |
|---|---|---|
| jobs_bronze.raw_events | 500 | ✅ |
| jobs_bronze.products | 30 | ✅ |
| jobs_silver.events_enriched | 500 | ✅ |
| jobs_gold.daily_sales rows | 115 | ✅ |
| Total sales amount | 12,814.84 | ✅ |
| Total order count | 119 | ✅ |
| Category count | 5 | ✅ |
| Studio tasks all ONLINE | 3/3 | ✅ |
Notes
--dep-tasksrequires both taskId and taskName: Passing only taskId will returntaskName is required. Both fields are mandatory.--foldertakes folder ID, not name: Query the ID withcz-cli task list-folders.- Task names cannot contain slashes: The
folder/tasknameformat will be parsed as a path in the CLI. Use the--folder <id>parameter to specify the folder, and only write the task name in the name field. --typeis required:cz-cli task createwill error without--type. Common types:PYTHON,SQL,SHELL.- Cron format conversion: Quartz 6-field (seconds minutes hours day month weekday) → standard 5-field (minutes hours day month weekday).
"0 0 2 * * ?"→"0 2 * * *".
Related Documentation
Studio Task Development
- Task Development and Scheduling: Creating, editing content, and scheduling Studio tasks
- Task Scheduling Dependencies: DAG dependency configuration details
- Studio Python Task Development Guide (ZettaPark)
- Studio Task Development and Operations (cz-cli)
Other Migration Guides
- Databricks Notebook → Lakehouse Migration Guide: Single Notebook → Studio task
- Databricks DLT → Lakehouse Migration Guide: Declarative pipeline migration
- Databricks Unity Catalog → Lakehouse Migration Guide: Permissions and governance
