<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Structured streaming for iceberg tables in Data Engineering</title>
    <link>https://community.databricks.com/t5/data-engineering/structured-streaming-for-iceberg-tables/m-p/143101#M52091</link>
    <description>&lt;P&gt;According to this&amp;nbsp;&lt;A href="https://iceberg.apache.org/docs/latest/spark-structured-streaming/" target="_self"&gt;https://iceberg.apache.org/docs/latest/spark-structured-streaming/&lt;/A&gt;&amp;nbsp;, we can stream from iceberg tables. I have ensured that my source table is Iceberg version 3, but no matter what I do, I get Iceberg does not streaming reads. Looking at V3 limitations here&amp;nbsp;&lt;A href="https://docs.databricks.com/gcp/en/iceberg/iceberg-v3?language=Managed+Iceberg+table#limitations" target="_self"&gt;https://docs.databricks.com/gcp/en/iceberg/iceberg-v3?language=Managed+Iceberg+table#limitations&lt;/A&gt;&amp;nbsp;, it does not mention that anywhere as a limitation. For version 2, one of limitation listed here&amp;nbsp;&lt;A href="https://docs.databricks.com/gcp/en/iceberg/" target="_self"&gt;https://docs.databricks.com/gcp/en/iceberg/&lt;/A&gt;&amp;nbsp;states that "&lt;SPAN&gt;Iceberg doesn't support&amp;nbsp;&lt;/SPAN&gt;&lt;A class="" href="https://docs.databricks.com/gcp/en/delta/delta-change-data-feed" target="_blank" rel="noopener"&gt;change data feed&lt;/A&gt;&lt;SPAN&gt;. As a result, incremental processing isn't supported when reading managed Iceberg tables as a source for:&lt;/SPAN&gt;"&lt;/P&gt;&lt;P&gt;But my destination is another iceberg table (also tried delta)&lt;/P&gt;&lt;P&gt;Error: data source iceberg does not support streamed reading&lt;/P&gt;&lt;LI-CODE lang="python"&gt;-- create source table
spark.sql("""CREATE OR REPLACE TABLE engagement.`sandbox-client-feedback`.dummy_iceberg_source_stream (c1 INT)
USING iceberg
TBLPROPERTIES ('format-version' = 3)""")

insert into engagement.`sandbox-client-feedback`.dummy_iceberg_source_stream values (2);

-- create destination table
spark.sql("""CREATE OR REPLACE TABLE engagement.`sandbox-client-feedback`.dummy_iceberg_destination (c1 INT)
USING iceberg""")

from pyspark.sql import SparkSession
from pyspark.sql.functions import *
import sys
from databricks.connect import DatabricksSession
import logging
import datetime


def stream_iceberg_to_iceberg(
    spark,
    source_table,
    target_table,
    checkpoint_location,
    trigger_interval_seconds=60,
    stream_start_timestamp=None
):
    """
    Stream data from source Iceberg table to target Iceberg table
    
    Args:
        spark: SparkSession instance
        source_table: Source Iceberg table name (e.g., 'catalog.database.source_table')
        target_table: Target Iceberg table name (e.g., 'catalog.database.target_table')
        checkpoint_location: Path for checkpoint files
        trigger_interval_seconds: Processing trigger interval in seconds (default: 60)
        stream_start_timestamp: Optional timestamp in milliseconds to start streaming from
    """
    
    # Configure streaming read from source Iceberg table
    read_stream_builder = (spark.readStream 
        .format("iceberg")
    )
    
    # Optional: Start from a specific timestamp
    if stream_start_timestamp:
        read_stream_builder = (read_stream_builder 
            .option("stream-from-timestamp", str(stream_start_timestamp))
        )
    
    # Optional: Configure streaming behavior
    read_stream_builder = (read_stream_builder 
        .option("streaming-skip-overwrite-snapshots", "true") 
        .option("streaming-skip-delete-snapshots", "true")
    )
    
    # Read the stream
    source_stream = read_stream_builder.load(source_table)
    
    # Optional: Apply transformations
    # Example: Add processing timestamp and filter
    transformed_stream = (source_stream 
        .withColumn("processing_time", current_timestamp()) 
        .withColumn("processing_date", current_date())
    )
    # Add your custom transformations here
    # .filter(col("some_column").isNotNull())
    # .select("col1", "col2", "col3")
    
    # Write stream to target Iceberg table
    query = (transformed_stream.writeStream 
        .format("iceberg") 
        .outputMode("append") 
        .trigger(availableNow=True) 
        .option("checkpointLocation", checkpoint_location) 
        .option("fanout-enabled", "true") 
        .toTable(target_table)
    )
    
    return query



def main():
    """
    Main execution function
    """
    # Configuration
    SOURCE_TABLE = "engagement.`sandbox-client-feedback`.dummy_iceberg_source_stream"
    TARGET_TABLE = "engagement.`sandbox-client-feedback`.dummy_iceberg_destination"
    CHECKPOINT_LOCATION = "dbfs:/dbfs/tmp/sum_streaming_iceberg_test_stream"
    
    start_time = int(datetime.datetime(2026, 1, 1).timestamp() * 1000)
    START_TIMESTAMP = start_time  # Set to None to start from latest snapshot
    
    # Create Spark session
    spark = DatabricksSession.builder.getOrCreate()
    spark.sparkContext.setLogLevel("INFO")
    
    logging.info(f"Starting streaming from {SOURCE_TABLE} to {TARGET_TABLE}")
    logging.info(f"Checkpoint location: {CHECKPOINT_LOCATION}")
    
    try:
        # Start streaming query
        query = stream_iceberg_to_iceberg(
            spark=spark,
            source_table=SOURCE_TABLE,
            target_table=TARGET_TABLE,
            checkpoint_location=CHECKPOINT_LOCATION,
            stream_start_timestamp=START_TIMESTAMP
        )
        
        logging.info(f"Streaming query started: {query.name}")
        logging.info("Press Ctrl+C to stop the streaming query")
        
        query.awaitTermination()
        
    except Exception as e:
        print(f"Error in streaming job: {str(e)}")


if __name__ == "__main__":
    main()

TBLPROPERTIES ('format-version' = 3);&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;DIV&gt;&lt;DIV class=""&gt;&lt;DIV class=""&gt;&lt;DIV&gt;&lt;DIV class=""&gt;&lt;DIV class=""&gt;&lt;DIV class=""&gt;&lt;DIV class=""&gt;&amp;nbsp;&lt;/DIV&gt;&lt;/DIV&gt;&lt;/DIV&gt;&lt;/DIV&gt;&lt;/DIV&gt;&lt;/DIV&gt;&lt;/DIV&gt;&lt;/DIV&gt;</description>
    <pubDate>Tue, 06 Jan 2026 15:12:17 GMT</pubDate>
    <dc:creator>SaugatMukherjee</dc:creator>
    <dc:date>2026-01-06T15:12:17Z</dc:date>
    <item>
      <title>Structured streaming for iceberg tables</title>
      <link>https://community.databricks.com/t5/data-engineering/structured-streaming-for-iceberg-tables/m-p/143101#M52091</link>
      <description>&lt;P&gt;According to this&amp;nbsp;&lt;A href="https://iceberg.apache.org/docs/latest/spark-structured-streaming/" target="_self"&gt;https://iceberg.apache.org/docs/latest/spark-structured-streaming/&lt;/A&gt;&amp;nbsp;, we can stream from iceberg tables. I have ensured that my source table is Iceberg version 3, but no matter what I do, I get Iceberg does not streaming reads. Looking at V3 limitations here&amp;nbsp;&lt;A href="https://docs.databricks.com/gcp/en/iceberg/iceberg-v3?language=Managed+Iceberg+table#limitations" target="_self"&gt;https://docs.databricks.com/gcp/en/iceberg/iceberg-v3?language=Managed+Iceberg+table#limitations&lt;/A&gt;&amp;nbsp;, it does not mention that anywhere as a limitation. For version 2, one of limitation listed here&amp;nbsp;&lt;A href="https://docs.databricks.com/gcp/en/iceberg/" target="_self"&gt;https://docs.databricks.com/gcp/en/iceberg/&lt;/A&gt;&amp;nbsp;states that "&lt;SPAN&gt;Iceberg doesn't support&amp;nbsp;&lt;/SPAN&gt;&lt;A class="" href="https://docs.databricks.com/gcp/en/delta/delta-change-data-feed" target="_blank" rel="noopener"&gt;change data feed&lt;/A&gt;&lt;SPAN&gt;. As a result, incremental processing isn't supported when reading managed Iceberg tables as a source for:&lt;/SPAN&gt;"&lt;/P&gt;&lt;P&gt;But my destination is another iceberg table (also tried delta)&lt;/P&gt;&lt;P&gt;Error: data source iceberg does not support streamed reading&lt;/P&gt;&lt;LI-CODE lang="python"&gt;-- create source table
spark.sql("""CREATE OR REPLACE TABLE engagement.`sandbox-client-feedback`.dummy_iceberg_source_stream (c1 INT)
USING iceberg
TBLPROPERTIES ('format-version' = 3)""")

insert into engagement.`sandbox-client-feedback`.dummy_iceberg_source_stream values (2);

-- create destination table
spark.sql("""CREATE OR REPLACE TABLE engagement.`sandbox-client-feedback`.dummy_iceberg_destination (c1 INT)
USING iceberg""")

from pyspark.sql import SparkSession
from pyspark.sql.functions import *
import sys
from databricks.connect import DatabricksSession
import logging
import datetime


def stream_iceberg_to_iceberg(
    spark,
    source_table,
    target_table,
    checkpoint_location,
    trigger_interval_seconds=60,
    stream_start_timestamp=None
):
    """
    Stream data from source Iceberg table to target Iceberg table
    
    Args:
        spark: SparkSession instance
        source_table: Source Iceberg table name (e.g., 'catalog.database.source_table')
        target_table: Target Iceberg table name (e.g., 'catalog.database.target_table')
        checkpoint_location: Path for checkpoint files
        trigger_interval_seconds: Processing trigger interval in seconds (default: 60)
        stream_start_timestamp: Optional timestamp in milliseconds to start streaming from
    """
    
    # Configure streaming read from source Iceberg table
    read_stream_builder = (spark.readStream 
        .format("iceberg")
    )
    
    # Optional: Start from a specific timestamp
    if stream_start_timestamp:
        read_stream_builder = (read_stream_builder 
            .option("stream-from-timestamp", str(stream_start_timestamp))
        )
    
    # Optional: Configure streaming behavior
    read_stream_builder = (read_stream_builder 
        .option("streaming-skip-overwrite-snapshots", "true") 
        .option("streaming-skip-delete-snapshots", "true")
    )
    
    # Read the stream
    source_stream = read_stream_builder.load(source_table)
    
    # Optional: Apply transformations
    # Example: Add processing timestamp and filter
    transformed_stream = (source_stream 
        .withColumn("processing_time", current_timestamp()) 
        .withColumn("processing_date", current_date())
    )
    # Add your custom transformations here
    # .filter(col("some_column").isNotNull())
    # .select("col1", "col2", "col3")
    
    # Write stream to target Iceberg table
    query = (transformed_stream.writeStream 
        .format("iceberg") 
        .outputMode("append") 
        .trigger(availableNow=True) 
        .option("checkpointLocation", checkpoint_location) 
        .option("fanout-enabled", "true") 
        .toTable(target_table)
    )
    
    return query



def main():
    """
    Main execution function
    """
    # Configuration
    SOURCE_TABLE = "engagement.`sandbox-client-feedback`.dummy_iceberg_source_stream"
    TARGET_TABLE = "engagement.`sandbox-client-feedback`.dummy_iceberg_destination"
    CHECKPOINT_LOCATION = "dbfs:/dbfs/tmp/sum_streaming_iceberg_test_stream"
    
    start_time = int(datetime.datetime(2026, 1, 1).timestamp() * 1000)
    START_TIMESTAMP = start_time  # Set to None to start from latest snapshot
    
    # Create Spark session
    spark = DatabricksSession.builder.getOrCreate()
    spark.sparkContext.setLogLevel("INFO")
    
    logging.info(f"Starting streaming from {SOURCE_TABLE} to {TARGET_TABLE}")
    logging.info(f"Checkpoint location: {CHECKPOINT_LOCATION}")
    
    try:
        # Start streaming query
        query = stream_iceberg_to_iceberg(
            spark=spark,
            source_table=SOURCE_TABLE,
            target_table=TARGET_TABLE,
            checkpoint_location=CHECKPOINT_LOCATION,
            stream_start_timestamp=START_TIMESTAMP
        )
        
        logging.info(f"Streaming query started: {query.name}")
        logging.info("Press Ctrl+C to stop the streaming query")
        
        query.awaitTermination()
        
    except Exception as e:
        print(f"Error in streaming job: {str(e)}")


if __name__ == "__main__":
    main()

TBLPROPERTIES ('format-version' = 3);&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;DIV&gt;&lt;DIV class=""&gt;&lt;DIV class=""&gt;&lt;DIV&gt;&lt;DIV class=""&gt;&lt;DIV class=""&gt;&lt;DIV class=""&gt;&lt;DIV class=""&gt;&amp;nbsp;&lt;/DIV&gt;&lt;/DIV&gt;&lt;/DIV&gt;&lt;/DIV&gt;&lt;/DIV&gt;&lt;/DIV&gt;&lt;/DIV&gt;&lt;/DIV&gt;</description>
      <pubDate>Tue, 06 Jan 2026 15:12:17 GMT</pubDate>
      <guid>https://community.databricks.com/t5/data-engineering/structured-streaming-for-iceberg-tables/m-p/143101#M52091</guid>
      <dc:creator>SaugatMukherjee</dc:creator>
      <dc:date>2026-01-06T15:12:17Z</dc:date>
    </item>
    <item>
      <title>Re: Structured streaming for iceberg tables</title>
      <link>https://community.databricks.com/t5/data-engineering/structured-streaming-for-iceberg-tables/m-p/143357#M52154</link>
      <description>&lt;P&gt;Greetings&amp;nbsp;&lt;a href="https://community.databricks.com/t5/user/viewprofilepage/user-id/20693"&gt;@SaugatMukherjee&lt;/a&gt;&amp;nbsp;, I did some research and this is what I found.&amp;nbsp;&lt;/P&gt;
&lt;P class="p1"&gt;You’re running into a real (and documented) Databricks limitation here: &lt;SPAN class="s2"&gt;&lt;STRONG&gt;managed Iceberg tables cannot be used as a streaming source today&lt;/STRONG&gt;&lt;/SPAN&gt;. That’s true even though upstream Apache Iceberg documents a Spark Structured Streaming read API.&lt;/P&gt;
&lt;P class="p1"&gt;Let’s unpack what’s going on and why your code behaves the way it does.&lt;/P&gt;
&lt;P class="p1"&gt;Let’s dig in…&lt;/P&gt;
&lt;H3&gt;&lt;STRONG&gt;What the docs actually say&lt;/STRONG&gt;&lt;/H3&gt;
&lt;P class="p1"&gt;Upstream &lt;SPAN class="s2"&gt;&lt;STRONG&gt;Apache Iceberg&lt;/STRONG&gt;&lt;/SPAN&gt; documentation shows support for Spark Structured Streaming reads using:&lt;/P&gt;
&lt;P class="p1"&gt;spark.readStream.format(“iceberg”)&lt;/P&gt;
&lt;P class="p1"&gt;This includes options like &lt;SPAN class="s3"&gt;stream-from-timestamp&lt;/SPAN&gt;, along with guardrails such as skipping overwrite or delete snapshots. In open-source Spark + Iceberg, that story is real.&lt;/P&gt;
&lt;P class="p1"&gt;However, Databricks’ own &lt;SPAN class="s2"&gt;&lt;STRONG&gt;Managed Iceberg table limitations&lt;/STRONG&gt;&lt;/SPAN&gt; documentation is explicit about the gap:&lt;/P&gt;
&lt;P class="p1"&gt;Iceberg does not support Change Data Feed (CDF). As a result, incremental processing is not supported when reading managed Iceberg tables as a source for materialized views and streaming tables.&lt;/P&gt;
&lt;P class="p1"&gt;That single sentence explains the behavior you’re seeing.&lt;/P&gt;
&lt;P class="p1"&gt;Even though:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;
&lt;P class="p1"&gt;Managed Iceberg is Public Preview in DBR 16.4+&lt;/P&gt;
&lt;/LI&gt;
&lt;LI&gt;
&lt;P class="p1"&gt;Iceberg v3 features are Beta in DBR 17.3+&lt;/P&gt;
&lt;/LI&gt;
&lt;/UL&gt;
&lt;P class="p1"&gt;…the absence of CDF means Databricks does not allow managed Iceberg tables to participate in incremental or streaming reads as a source.&lt;/P&gt;
&lt;P class="p2"&gt;&amp;nbsp;&lt;/P&gt;
&lt;H3&gt;&lt;STRONG&gt;Why you see “data source iceberg does not support streamed reading”&lt;/STRONG&gt;&lt;/H3&gt;
&lt;P class="p1"&gt;On Databricks, the Iceberg connector shipped with the runtime does not expose a streaming source implementation.&lt;/P&gt;
&lt;P class="p1"&gt;Databricks’ streaming and incremental features lean heavily on &lt;SPAN class="s2"&gt;&lt;STRONG&gt;Change Data Feed&lt;/STRONG&gt;&lt;/SPAN&gt; as the underlying mechanism. Because OSS Iceberg doesn’t have CDF today, Databricks intentionally disables streaming reads from managed Iceberg tables.&lt;/P&gt;
&lt;P class="p1"&gt;Operationally, that shows up exactly as the error you hit:&lt;/P&gt;
&lt;P class="p1"&gt;“data source iceberg does not support streamed reading”&lt;/P&gt;
&lt;P class="p1"&gt;Even though the options you set (&lt;SPAN class="s3"&gt;stream-from-timestamp&lt;/SPAN&gt;, &lt;SPAN class="s3"&gt;streaming-skip-overwrite-snapshots&lt;/SPAN&gt;, etc.) are valid in upstream Iceberg, Databricks will reject the read regardless. This is a platform constraint, not a configuration issue.&lt;/P&gt;
&lt;H3&gt;&lt;STRONG&gt;What works vs. what doesn’t on Databricks today&lt;/STRONG&gt;&lt;/H3&gt;
&lt;P class="p1"&gt;Here’s the clean line in the sand:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;
&lt;P class="p1"&gt;Streaming reads from &lt;SPAN class="s1"&gt;&lt;STRONG&gt;managed Iceberg tables as a source&lt;/STRONG&gt;&lt;/SPAN&gt; are not supported.&lt;/P&gt;
&lt;/LI&gt;
&lt;LI&gt;
&lt;P class="p1"&gt;Incremental features like streaming tables, materialized views, and similar services cannot read managed Iceberg input today.&lt;/P&gt;
&lt;/LI&gt;
&lt;LI&gt;
&lt;P class="p1"&gt;Upstream Iceberg examples showing streaming reads and writes do not apply to Databricks-managed Iceberg yet.&lt;/P&gt;
&lt;/LI&gt;
&lt;/UL&gt;
&lt;P class="p1"&gt;The sink side (writing to Iceberg) is not your problem. The read side is.&lt;/P&gt;
&lt;H3&gt;&lt;STRONG&gt;Practical options and workarounds&lt;/STRONG&gt;&lt;/H3&gt;
&lt;P class="p1"&gt;If you need true streaming or CDC-style incremental processing today, the supported path is:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;
&lt;P class="p1"&gt;&lt;SPAN class="s1"&gt;Keep your &lt;/SPAN&gt;&lt;STRONG&gt;source in Delta&lt;/STRONG&gt;&lt;/P&gt;
&lt;/LI&gt;
&lt;LI&gt;
&lt;P class="p1"&gt;&lt;SPAN class="s1"&gt;Enable &lt;/SPAN&gt;&lt;STRONG&gt;Change Data Feed&lt;/STRONG&gt;&lt;/P&gt;
&lt;/LI&gt;
&lt;LI&gt;
&lt;P class="p1"&gt;Read via Structured Streaming with &lt;SPAN class="s1"&gt;readChangeFeed = true&lt;/SPAN&gt;&lt;/P&gt;
&lt;/LI&gt;
&lt;/UL&gt;
&lt;P class="p1"&gt;That pattern is battle-tested and fully supported on Databricks.&lt;/P&gt;
&lt;P class="p1"&gt;If your source must remain Iceberg, the viable alternative is a &lt;SPAN class="s2"&gt;&lt;STRONG&gt;scheduled batch micro-batch pattern&lt;/STRONG&gt;&lt;/SPAN&gt;:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;
&lt;P class="p1"&gt;Read the Iceberg table in batch:&lt;/P&gt;
&lt;P class="p1"&gt;spark.read.table(“catalog.schema.table”)&lt;/P&gt;
&lt;/LI&gt;
&lt;LI&gt;
&lt;P class="p1"&gt;Transform and append to your destination (Iceberg or Delta) using batch writes&lt;/P&gt;
&lt;/LI&gt;
&lt;LI&gt;
&lt;P class="p1"&gt;Persist a watermark (timestamp or snapshot ID) in a control table&lt;/P&gt;
&lt;/LI&gt;
&lt;LI&gt;
&lt;P class="p1"&gt;Filter “new” data on each run&lt;/P&gt;
&lt;/LI&gt;
&lt;/UL&gt;
&lt;P class="p1"&gt;This gives you near-real-time behavior via frequent Jobs runs, but it is still batch, not streaming. There is no Databricks-managed Iceberg streaming source to cite today.&lt;/P&gt;
&lt;P class="p1"&gt;If your downstream targets include materialized views, streaming tables, Lakehouse Monitoring, or other incremental services, the practical guidance is to &lt;SPAN class="s2"&gt;&lt;STRONG&gt;land or replicate into Delta&lt;/STRONG&gt;&lt;/SPAN&gt; so those services can leverage CDF and row tracking.&lt;/P&gt;
&lt;H3&gt;&lt;STRONG&gt;Notes on your code specifically&lt;/STRONG&gt;&lt;/H3&gt;
&lt;P class="p1"&gt;The failure is happening right here:&lt;/P&gt;
&lt;P class="p1"&gt;spark.readStream.format(“iceberg”).load(source_table)&lt;/P&gt;
&lt;P class="p1"&gt;On Databricks, that call will error for managed Iceberg sources every time. Swapping options won’t change the outcome.&lt;/P&gt;
&lt;P class="p1"&gt;Your choices are:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;
&lt;P class="p1"&gt;Replace this with a batch read and schedule it, or&lt;/P&gt;
&lt;/LI&gt;
&lt;LI&gt;
&lt;P class="p1"&gt;Change the source to Delta with CDF if you need a true streaming pipeline&lt;/P&gt;
&lt;/LI&gt;
&lt;/UL&gt;
&lt;P class="p1"&gt;Again, your sink choice (Iceberg vs Delta) is not the issue—the source read is.&lt;/P&gt;
&lt;H3&gt;&lt;STRONG&gt;Minimal batch example: Iceberg → Iceberg on Databricks&lt;/STRONG&gt;&lt;/H3&gt;
&lt;P class="p1"&gt;Here’s the simplest supported pattern:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE&gt;from pyspark.sql import functions as F

SOURCE_TABLE = "engagement.`sandbox-client-feedback`.dummy_iceberg_source_stream"
TARGET_TABLE = "engagement.`sandbox-client-feedback`.dummy_iceberg_destination"

df = (
    spark.read.table(SOURCE_TABLE)
         .withColumn("processing_time", F.current_timestamp())
         .withColumn("processing_date", F.current_date())
)

(df.write
   .format("iceberg")
   .mode("append")
   .saveAsTable(TARGET_TABLE))&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P class="p1"&gt;Schedule this with Jobs every N minutes, and persist a “last processed” watermark to avoid reprocessing. It’s batch, but it’s the closest operational equivalent available today.&lt;/P&gt;
&lt;H3&gt;&lt;STRONG&gt;Bottom line&lt;/STRONG&gt;&lt;/H3&gt;
&lt;P class="p1"&gt;If you need streaming &lt;SPAN class="s2"&gt;&lt;STRONG&gt;today&lt;/STRONG&gt;&lt;/SPAN&gt;, Delta + CDF is the supported answer on Databricks.&lt;/P&gt;
&lt;P class="p1"&gt;If you need to stay on Iceberg, the path forward is scheduled batch with explicit state management—until Databricks enables an Iceberg-compatible incremental source.&lt;/P&gt;
&lt;P class="p1"&gt;Hope this provides some guidance.&lt;/P&gt;
&lt;P class="p1"&gt;Regars, Louis.&lt;/P&gt;</description>
      <pubDate>Thu, 08 Jan 2026 14:20:28 GMT</pubDate>
      <guid>https://community.databricks.com/t5/data-engineering/structured-streaming-for-iceberg-tables/m-p/143357#M52154</guid>
      <dc:creator>Louis_Frolio</dc:creator>
      <dc:date>2026-01-08T14:20:28Z</dc:date>
    </item>
    <item>
      <title>Re: Structured streaming for iceberg tables</title>
      <link>https://community.databricks.com/t5/data-engineering/structured-streaming-for-iceberg-tables/m-p/143489#M52186</link>
      <description>&lt;P&gt;Hi,&lt;/P&gt;&lt;P&gt;Iceberg streaming is possible in Databricks. One does not need to change to Delta Lake. In my previous attempt, I used "load" while reading the source iceberg table. One should instead use "table". Load apparently seems to take a path and not a table name.&lt;/P&gt;&lt;P&gt;This is correct code to stream from Iceberg table.&lt;/P&gt;&lt;LI-CODE lang="python"&gt;from pyspark.sql.functions import current_timestamp

source_stream = (spark.readStream 
    .format("iceberg") 
    .table("engagement.`sandbox-client-feedback`.dummy_iceberg_source_stream")
    .withColumn("_ProcessedTime", current_timestamp())
)

query = (source_stream.writeStream 
    .format("iceberg") 
    .outputMode("append") 
    .trigger(availableNow=True) 
    .option("checkpointLocation", "/tmp/checkpoint/testicebergdestination") 
    .toTable("engagement.`sandbox-client-feedback`.dummy_iceberg_destination")
)
query.awaitTermination()&lt;/LI-CODE&gt;</description>
      <pubDate>Fri, 09 Jan 2026 14:16:09 GMT</pubDate>
      <guid>https://community.databricks.com/t5/data-engineering/structured-streaming-for-iceberg-tables/m-p/143489#M52186</guid>
      <dc:creator>SaugatMukherjee</dc:creator>
      <dc:date>2026-01-09T14:16:09Z</dc:date>
    </item>
  </channel>
</rss>

