Loading...
Loading...
Compare original and translation side by side
- [ ] Language selected: Python or SQL
- [ ] Compute type decided: serverless or classic compute
- [ ] Decide on multiple catalogs or schemas vs. all in one default schema
- [ ] Consider what should be parameterized at the pipeline level to make deployment easy.
- [ ] Consider [Multi-Schema Patterns](#multi-schema-patterns) below, ask if unclear on best choices.
- [ ] Consider [Modern Defaults](#modern-defaults) below, ask if unclear on best choices.- [ ] 已选择语言:Python或SQL
- [ ] 已确定计算类型:无服务器或经典计算
- [ ] 已确定使用多目录/多Schema还是全部放在默认Schema中
- [ ] 考虑哪些内容需要在管道层面参数化,以便简化部署
- [ ] 参考下方的[多Schema模式](#多-schema-模式),若对最佳选择有疑问请询问用户
- [ ] 参考下方的[现代默认配置](#现代默认配置),若对最佳选择有疑问请询问用户databricks pipelines initdatabricks pipelines initdatabricks pipelines initcustomer_orders_pipelinemainprod_catalogyesnomy_pipeline/
├── databricks.yml # Multi-environment config (dev/prod)
├── resources/
│ └── *_etl.pipeline.yml # Pipeline resource definition
└── src/
└── *_etl/
├── explorations/ # Exploratory code in .ipynb
└── transformations/ # Your .sql or .py files heredatabricks pipelines initcustomer_orders_pipelinemainprod_catalogyesnomy_pipeline/
├── databricks.yml # 多环境配置(开发/生产)
├── resources/
│ └── *_etl.pipeline.yml # 管道资源定义
└── src/
└── *_etl/
├── explorations/ # .ipynb格式的探索性代码
└── transformations/ # 存放你的.sql或.py文件src/transformations//Volumes/{catalog}/{schema}/{pipeline_name}_metadata/schemassrc/transformations//Volumes/{catalog}/{schema}/{pipeline_name}_metadata/schemasundefinedundefinedundefinedundefined| Concept | Details |
|---|---|
| Names | SDP = Spark Declarative Pipelines = LDP = Lakeflow Declarative Pipelines = Lakeflow Pipelines (all interchangeable) |
| Python Import | |
| Primary Decorators | |
| Temporary Views | |
| Replaces | Delta Live Tables (DLT) with |
| Based On | Apache Spark 4.1+ (Databricks' modern data pipeline framework) |
| Docs | https://docs.databricks.com/aws/en/ldp/developer/python-dev |
| 概念 | 详情 |
|---|---|
| 名称对应 | SDP = Spark Declarative Pipelines = LDP = Lakeflow Declarative Pipelines = Lakeflow Pipelines(以上名称可互换) |
| Python导入语句 | |
| 主要装饰器 | |
| 临时视图 | |
| 替代方案 | 替代使用 |
| 基于框架 | Apache Spark 4.1+(Databricks的现代数据管道框架) |
| 官方文档 | https://docs.databricks.com/aws/en/ldp/developer/python-dev |
pyspark.pipelinesdltdatabricks pipelines initpyspark.pipelinesdltdatabricks pipelines initpyspark.pipelinespyspark.pipelines_ingested_at_source_filebronze_*.sqlsilver_*.sqlgold_*.sqlbronze/orders.sqlsilver/cleaned.sqlgold/summary.sqltransformations/**_ingested_at_source_filebronze_*.sqlsilver_*.sqlgold_*.sqlbronze/orders.sqlsilver/cleaned.sqlgold/summary.sqltransformations/**.sql.pymy_pipeline/
├── bronze/
│ ├── ingest_orders.sql # SQL (default for most cases)
│ └── ingest_events.py # Python (for complex logic)
├── silver/
│ └── clean_orders.sql
└── gold/
└── daily_summary.sqlbronze/ingest_orders.sqlCREATE OR REFRESH STREAMING TABLE bronze_orders
CLUSTER BY (order_date)
AS
SELECT
*,
current_timestamp() AS _ingested_at,
_metadata.file_path AS _source_file
FROM read_files(
'/Volumes/catalog/schema/raw/orders/',
format => 'json',
schemaHints => 'order_id STRING, customer_id STRING, amount DECIMAL(10,2), order_date DATE'
);bronze/ingest_events.pyfrom pyspark import pipelines as dp
from pyspark.sql.functions import col, current_timestamp.sql.pymy_pipeline/
├── bronze/
│ ├── ingest_orders.sql # SQL(大多数场景的默认选择)
│ └── ingest_events.py # Python(用于复杂逻辑)
├── silver/
│ └── clean_orders.sql
└── gold/
└── daily_summary.sqlbronze/ingest_orders.sqlCREATE OR REFRESH STREAMING TABLE bronze_orders
CLUSTER BY (order_date)
AS
SELECT
*,
current_timestamp() AS _ingested_at,
_metadata.file_path AS _source_file
FROM read_files(
'/Volumes/catalog/schema/raw/orders/',
format => 'json',
schemaHints => 'order_id STRING, customer_id STRING, amount DECIMAL(10,2), order_date DATE'
);bronze/ingest_events.pyfrom pyspark import pipelines as dp
from pyspark.sql.functions import col, current_timestamp
**IMPORTANT for Python Pipelines**: When using `spark.readStream.format("cloudFiles")` for cloud storage ingestion, with schema inference (no schema specified), you **must specify a schema location**.
**Always ask the user** where to store Auto Loader schema metadata. Recommend:
Example: `/Volumes/my_catalog/pipeline_metadata/orders_pipeline_metadata/schemas`
**Never use the source data volume** - this causes permission conflicts. The schema location should be configured in the pipeline settings and accessed via `spark.conf.get("schema_location_base")`.
**Language Selection:**
**CRITICAL RULE**: If the user explicitly mentions "Python" in their request (e.g., "Python Spark Declarative Pipeline", "Python SDP", "use Python"), **ALWAYS use Python without asking**. The same applies to SQL - if they say "SQL pipeline", use SQL.
- **Explicit language request**: User says "Python" → Use Python. User says "SQL" → Use SQL. **Do not ask for clarification.**
- **Auto-detection** (only when no explicit language mentioned):
- **SQL indicators**: "sql files", "simple transformations", "aggregations", "materialized view", "CREATE OR REFRESH"
- **Python indicators**: ".py files", "UDF", "complex logic", "ML inference", "external API", "@dp.table", "pandas", "decorator"
- **Prompt for clarification** only when language intent is truly ambiguous (no explicit mention, mixed signals)
- **Default to SQL** only when ambiguous AND no Python indicators present
See **[8-project-initialization.md](8-project-initialization.md)** for detailed language detection logic.
**Python管道重要提示**:当使用`spark.readStream.format("cloudFiles")`从云存储摄入数据且启用Schema推断(未指定Schema)时,**必须指定Schema存储位置**。
**请始终询问用户**Auto Loader Schema元数据的存储位置。推荐路径:
示例:`/Volumes/my_catalog/pipeline_metadata/orders_pipeline_metadata/schemas`
**绝不要使用源数据卷** - 这会导致权限冲突。Schema存储位置应在管道设置中配置,并通过`spark.conf.get("schema_location_base")`访问。
**语言选择规则:**
**核心规则**:如果用户在请求中明确提及"Python"(例如"Python Spark Declarative Pipeline"、"Python SDP"、"使用Python"),**始终使用Python,无需询问**。SQL同理 - 如果用户说"SQL pipeline",则使用SQL。
- **明确语言请求**:用户说"Python" → 使用Python;用户说"SQL" → 使用SQL。**无需进一步确认。**
- **自动检测**(仅当未明确提及语言时):
- **SQL标识**:"sql files"、"简单转换"、"聚合"、"物化视图"、"CREATE OR REFRESH"
- **Python标识**:".py files"、"UDF"、"复杂逻辑"、"ML推理"、"外部API"、"@dp.table"、"pandas"、"装饰器"
- **仅当语言意图真正模糊时**(未明确提及,信号混合)才提示确认
- **仅当模糊且无Python标识时**默认使用SQL
有关详细的语言检测逻辑,请参考**[8-project-initialization.md](8-project-initialization.md)**。create_or_update_pipelinecreate_or_update_pipelinedatabricks pipelines initbronze_*.sqlsilver_*.sqlgold_*.sqltransformations/transformations/bronze/transformations/silver/transformations/gold/transformations/**databricks pipelines inittransformations/bronze_*.sqlsilver_*.sqlgold_*.sqltransformations/bronze/transformations/silver/transformations/gold/transformations/**resources.pipelines.<pipeline>.configurationdatabricks bundle validate.sql.py.sql.pycatalogschemacatalogschemaundefinedundefined
**Advantages:**
- Simpler configuration (one pipeline)
- All tables in one schema for easy discovery
**优势:**
- 配置更简单(仅一个管道)
- 所有表在一个Schema中,便于发现from pyspark import pipelines as dp
from pyspark.sql.functions import colfrom pyspark import pipelines as dp
from pyspark.sql.functions import col- Using unqualified names for bronze ensures it lands in the pipeline’s default catalog/schema; silver/gold are explicitly schema-qualified within the same catalog.
---- 青铜层使用非限定名称确保数据写入管道的默认catalog/schema;白银/黄金层在同一catalog内使用明确的schema限定名称。
---from pyspark import pipelines as dp
from pyspark.sql.functions import colfrom pyspark import pipelines as dp
from pyspark.sql.functions import col- Multipart names in the decorator’s name argument let you publish to explicit catalog.schema targets within one pipeline.
- Unqualified reads/writes use the pipeline defaults; use fully-qualified names when crossing catalogs or when you need explicit namespace control.
---
**Note:** The `@dp.table()` decorator does not currently support separate for `schema=` or `catalog=` parameters. The table parameter is a string that contains the catalog.schema.table_name, or it can leave off catalog and or schema to use the pipeilnes configured default target schema.- 装饰器的name参数中使用多部分名称,可在一个管道内将表发布到明确的catalog.schema目标位置。
- 非限定读写操作使用管道默认配置;跨catalog或需要明确命名空间控制时使用完全限定名称。
---
**注意:**`@dp.table()`装饰器目前不支持单独的`schema=`或`catalog=`参数。table参数是一个包含catalog.schema.table_name的字符串,也可省略catalog和/或schema以使用管道配置的默认目标schema。spark.read.table()spark.readStream.table()dp.read()dp.read_stream()dlt.read()dlt.read_stream()spark.read.table()spark.readStream.table()dp.read()dp.read_stream()dlt.read()dlt.read_stream()| Level | Syntax | When to Use |
|---|---|---|
| Unqualified | | Reading tables within the same pipeline's target catalog/schema (recommended) |
| Partially-qualified | | Reading from different schema in same catalog |
| Fully-qualified | | Reading from external catalogs/schemas |
| 级别 | 语法 | 使用场景 |
|---|---|---|
| 非限定名称 | | 读取同一管道目标catalog/schema内的表(推荐) |
| 部分限定名称 | | 读取同一catalog下其他schema中的表 |
| 完全限定名称 | | 读取外部catalog/schema中的表 |
@dp.table(name="silver_clean")
def silver_clean():
# Reads from pipeline's target catalog/schema (e.g., dev_catalog.dev_schema.bronze_raw)
return (
spark.read.table("bronze_raw")
.filter(F.col("valid") == True)
)
@dp.table(name="silver_events")
def silver_events():
# Streaming read from same pipeline's bronze_events table
return (
spark.readStream.table("bronze_events")
.withColumn("processed_at", F.current_timestamp())
)@dp.table(name="silver_clean")
def silver_clean():
# 读取管道目标catalog/schema中的表(例如dev_catalog.dev_schema.bronze_raw)
return (
spark.read.table("bronze_raw")
.filter(F.col("valid") == True)
)
@dp.table(name="silver_events")
def silver_events():
# 读取同一管道内的bronze_events表的流数据
return (
spark.readStream.table("bronze_events")
.withColumn("processed_at", F.current_timestamp())
)spark.conf.get()from pyspark import pipelines as dp
from pyspark.sql import functions as Fspark.conf.get()from pyspark import pipelines as dp
from pyspark.sql import functions as F
**Configure parameters in pipeline settings:**
- **Asset Bundles**: Add to `pipeline.yml` under `configuration:`
- **Manual/MCP**: Pass via `extra_settings.configuration` dict
```yaml
**在管道设置中配置参数:**
- **Asset Bundles**:添加到`pipeline.yml`的`configuration:`下
- **手动/MCP**:通过`extra_settings.configuration`字典传递
```yamlundefinedundefined@dp.table(name="enriched_orders")
def enriched_orders():
# Pipeline-internal table (unqualified)
orders = spark.read.table("bronze_orders")
# External reference table (fully-qualified)
products = spark.read.table("shared_catalog.reference.products")
return orders.join(products, "product_id")@dp.table(name="enriched_orders")
def enriched_orders():
# 管道内表(非限定名称)
orders = spark.read.table("bronze_orders")
# 外部参考表(完全限定名称)
products = spark.read.table("shared_catalog.reference.products")
return orders.join(products, "product_id")| Scenario | Recommended Approach |
|---|---|
| Reading tables created in same pipeline | Unqualified names - portable, uses target catalog/schema |
| Reading from external source that varies by environment | Pipeline parameters - configurable per deployment |
| Reading from shared/reference tables with fixed location | Fully-qualified names - explicit and clear |
| Mixed pipeline (some internal, some external) | Combine approaches - unqualified for internal, parameters for external |
| 场景 | 推荐方式 |
|---|---|
| 读取同一管道内创建的表 | 非限定名称 - 可移植,使用目标catalog/schema |
| 读取跨环境变化的外部源 | 管道参数 - 可按部署环境配置 |
| 读取位置固定的共享/参考表 | 完全限定名称 - 明确清晰 |
| 混合管道(部分内部表,部分外部表) | 组合方式 - 内部表使用非限定名称,外部源使用参数 |
| Issue | Solution |
|---|---|
| Empty output tables | Use |
| Pipeline stuck INITIALIZING | Normal for serverless, wait a few minutes |
| "Column not found" | Check |
| Streaming reads fail | For file ingestion in a streaming table, you must use the |
| Timeout during run | Increase |
| MV doesn't refresh | Enable row tracking on source tables |
| SCD2: query column not found | Lakeflow uses |
| AUTO CDC parse error at APPLY/SEQUENCE | Put |
| "Cannot create streaming table from batch query" | In a streaming table query, use |
result["message"]create_or_update_pipelineget_pipeline_events(pipeline_id=...)| 问题 | 解决方案 |
|---|---|
| 输出表为空 | 使用 |
| 管道卡在INITIALIZING状态 | 无服务器管道的正常现象,请等待几分钟 |
| "列未找到" | 检查 |
| 流读取失败 | 对于流表中的文件摄入,必须在 |
| 运行时超时 | 增加 |
| 物化视图不刷新 | 启用源表的行跟踪功能 |
| SCD2:查询列未找到 | Lakeflow使用 |
| AUTO CDC在APPLY/SEQUENCE处解析错误 | 将 |
| "无法从批处理查询创建流表" | 在流表查询中,使用 |
create_or_update_pipelineresult["message"]get_pipeline_events(pipeline_id=...)| Requirement | Details |
|---|---|
| Unity Catalog | Required - serverless pipelines always use UC |
| Workspace Region | Must be in serverless-enabled region |
| Serverless Terms | Must accept serverless terms of use |
| CDC Features | Requires serverless (or Pro/Advanced with classic clusters) |
| 要求 | 详情 |
|---|---|
| Unity Catalog | 必需 - 无服务器管道始终使用UC |
| 工作区区域 | 必须在支持无服务器的区域 |
| 无服务器条款 | 必须接受无服务器服务条款 |
| CDC功能 | 需要无服务器(或使用经典集群的专业/高级版) |
| Limitation | Workaround |
|---|---|
| R language | Not supported - use classic clusters if required |
| Spark RDD APIs | Not supported - use classic clusters if required |
| JAR libraries | Not supported - use classic clusters if required |
| Maven coordinates | Not supported - use classic clusters if required |
| DBFS root access | Limited - must use Unity Catalog external locations |
| Global temp views | Not supported |
| 限制 | 替代方案 |
|---|---|
| R语言 | 不支持 - 若需要则使用经典集群 |
| Spark RDD API | 不支持 - 若需要则使用经典集群 |
| JAR库 | 不支持 - 若需要则使用经典集群 |
| Maven坐标 | 不支持 - 若需要则使用经典集群 |
| DBFS根目录访问 | 受限 - 必须使用Unity Catalog外部位置 |
| 全局临时视图 | 不支持 |
| Constraint | Details |
|---|---|
| Schema Evolution | Streaming tables require full refresh for incompatible changes |
| SQL Limitations | PIVOT clause unsupported |
| Sinks | Python only, streaming only, append flows only |
| 限制 | 详情 |
|---|---|
| Schema演化 | 流表的不兼容变更需要全量刷新 |
| SQL限制 | 不支持PIVOT子句 |
| 输出端 | 仅支持Python、仅支持流处理、仅支持追加流 |