Write actions¶
A write action has type: write and a write_target block. The
write_target.type field selects the target: streaming_table,
materialized_view, or sink. This page lists every write_target
field, the mode-specific config blocks, and the Lakeflow construct each target
emits.
See also
How-to guides: Configure a streaming table write, Apply CDC changes to a streaming table, Build a dimension from periodic snapshots, Write a materialized view, Write to an external sink.
Streaming table¶
write_target.type: streaming_table. Handler:
StreamingTableWriteGenerator. The mode field selects the flow shape.
Key |
Type |
Default |
Notes |
|---|---|---|---|
|
string |
|
One of |
source may be a single view or a list of views (multi-source append flow
into one table).
- name: write_customer_silver
type: write
source: v_customer_bronze
write_target:
type: streaming_table
mode: standard
catalog: "${catalog}"
schema: "${silver_schema}"
table: customer_dim
Emitted constructs¶
standard:dp.create_streaming_table(...)(whencreate_tableis true) plus one@dp.append_flow(target=, name=, comment=)decorator per source view.cdc:dp.create_streaming_table(...)(whencreate_tableis true) plusdp.create_auto_cdc_flow(...).snapshot_cdc:dp.create_streaming_table(...)(always) plusdp.create_auto_cdc_from_snapshot_flow(...).
mode: cdc¶
mode: cdc requires a cdc_config block. Fields under
write_target.cdc_config:
Key |
Type |
Default |
Notes |
|---|---|---|---|
|
list[string] |
required |
Non-empty business keys. |
|
string / list[string] |
— |
Ordering column(s); a list emits |
|
int |
|
|
|
bool |
— |
— |
|
string |
— |
SQL expression. |
|
string |
— |
SQL expression; not allowed with |
|
list[string] |
— |
|
|
list[string] |
— |
|
|
list[string] |
— |
Mutually exclusive with |
|
list[string] |
— |
Mutually exclusive with |
- name: write_customer_silver
type: write
source: v_customer_bronze
write_target:
type: streaming_table
mode: cdc
catalog: "${catalog}"
schema: "${silver_schema}"
table: customer_dim
cdc_config:
keys: ["customer_id"]
sequence_by: "last_modified_dt"
scd_type: 2
mode: snapshot_cdc¶
mode: snapshot_cdc requires a snapshot_cdc_config block and forces
create_table: true. Fields under write_target.snapshot_cdc_config:
Key |
Type |
Default |
Notes |
|---|---|---|---|
|
string |
one-of |
External table/path; exactly one of |
|
dict |
one-of |
|
|
list[string] |
required |
Non-empty. |
|
int |
|
|
|
list[string] |
— |
Mutually exclusive with |
|
list[string] |
— |
Mutually exclusive with |
With source_function, each parameters entry is bound as a keyword
argument via functools.partial (the function must declare them as
keyword-only args after *); source_function.file is copied alongside
the generated pipeline and resolved relative to project root.
- name: write_customer_snapshot
type: write
write_target:
type: streaming_table
mode: snapshot_cdc
catalog: "${catalog}"
schema: "${silver_schema}"
table: customer_dim
snapshot_cdc_config:
source: "${catalog}.${bronze_schema}.customer_snapshot"
keys: ["customer_id"]
stored_as_scd_type: 2
Materialized view¶
write_target.type: materialized_view. Handler:
MaterializedViewWriteGenerator. Emits a @dp.materialized_view(...)
decorated function. Uses the shared fields above plus the fields below.
Key |
Type |
Default |
Notes |
|---|---|---|---|
|
string |
— |
Inline query; one of |
|
string |
— |
External |
|
string |
— |
Cron/schedule; emitted as |
|
string |
— |
One of |
Define the view by exactly one of: an action-level source view, inline
sql, or sql_path. When sql/sql_path is provided, no
action-level source is needed.
- name: write_customer_summary
type: write
write_target:
type: materialized_view
catalog: "${catalog}"
schema: "${gold_schema}"
table: customer_summary
sql: "SELECT customer_id, COUNT(*) AS orders FROM v_orders GROUP BY customer_id"
Sink¶
write_target.type: sink. Handler: SinkWriteGenerator dispatches on
sink_type. Every sink emits
dp.create_sink(name=, format=, options=) plus one
@dp.append_flow(target=<sink_name>, name="f_<sink_name>_<index>",
comment=) per source view, reading the source with
spark.readStream.table(...).
Key |
Type |
Default |
Notes |
|---|---|---|---|
|
string |
required |
|
|
string |
— |
Unique sink identifier; used in the emitted flow names. |
|
dict |
|
Sink options. |
|
string |
derived |
— |
sink_type-specific fields¶
sink_type |
Additional fields |
Notes |
|---|---|---|
|
|
Format fixed |
|
|
Format fixed |
|
|
No separate |
|
|
Exactly one of |
|
|
Writes through a user-supplied PySpark |
- name: write_orders_to_delta_sink
type: write
source: v_orders
write_target:
type: sink
sink_type: delta
sink_name: orders_delta_sink
options:
tableName: "${catalog}.${gold_schema}.orders_export"
- name: write_orders_to_kafka_sink
type: write
source: v_orders_for_kafka
write_target:
type: sink
sink_type: kafka
sink_name: order_events_kafka
bootstrap_servers: "${kafka_bootstrap_cluster}"
topic: "acme.orders.fulfillment"
options:
kafka.security.protocol: "SASL_SSL"
kafka.sasl.mechanism: "PLAIN"
- name: write_orders_to_eventhubs
type: write
source: v_orders_for_eventhubs
write_target:
type: sink
sink_type: kafka
sink_name: order_events_eventhubs
bootstrap_servers: "${eh_namespace}.servicebus.windows.net:9093"
topic: "acme-orders"
options:
kafka.security.protocol: "SASL_SSL"
kafka.sasl.mechanism: "OAUTHBEARER"
- name: merge_customer_updates
type: write
source: v_customer_changes
write_target:
type: sink
sink_type: foreachbatch
sink_name: customer_merge_sink
batch_handler: |
df.createOrReplaceTempView("batch_view")
df.sparkSession.sql("MERGE INTO ${catalog}.${gold_schema}.dim_customer ...")
- name: write_to_custom_sink
type: write
source: v_seed_rows
write_target:
type: sink
sink_type: custom
sink_name: backed_sink
module_path: "py_functions/custom_sink.py"
custom_sink_class: "MyCustomSink"
options:
output_path: "/tmp/custom_sink_output"