<?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 What happens to with SCD2 tables if the source pipeline performs a Full Refresh? in Data Engineering</title>
    <link>https://community.databricks.com/t5/data-engineering/what-happens-to-with-scd2-tables-if-the-source-pipeline-performs/m-p/164066#M55221</link>
    <description>&lt;P class=""&gt;&lt;SPAN&gt;Hi everyone,&lt;/SPAN&gt;&lt;/P&gt;&lt;P class=""&gt;&lt;SPAN&gt;I'm looking for clarification on how Lakeflow/DLT behaves in the following scenario.&lt;/SPAN&gt;&lt;/P&gt;&lt;P class=""&gt;&lt;SPAN&gt;We have two independent pipelines:&lt;/SPAN&gt;&lt;/P&gt;&lt;P class=""&gt;&lt;STRONG&gt;&lt;SPAN&gt;Pipeline 1 (Ingestion)&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;/P&gt;&lt;UL&gt;&lt;LI&gt;&lt;SPAN&gt;Ingests Salesforce objects into Delta tables.&lt;/SPAN&gt;&lt;/LI&gt;&lt;LI&gt;&lt;SPAN&gt;These tables represent the current snapshot of Salesforce.&lt;/SPAN&gt;&lt;/LI&gt;&lt;LI&gt;&lt;SPAN&gt;Once a week, we plan to run this pipeline with &lt;/SPAN&gt;&lt;STRONG&gt;&lt;SPAN&gt;Full Refresh&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;SPAN&gt; (&lt;/SPAN&gt;&lt;SPAN&gt;full_refresh: true&lt;/SPAN&gt;&lt;SPAN&gt;) because records and columns are sometimes deleted in Salesforce, and incremental ingestion doesn't always reflect those deletions.&lt;/SPAN&gt;&lt;/LI&gt;&lt;/UL&gt;&lt;P class=""&gt;&lt;STRONG&gt;&lt;SPAN&gt;Pipeline 2 (SCD2)&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;/P&gt;&lt;P class=""&gt;&lt;SPAN&gt;For each ingested table, we have a separate pipeline that creates an SCD2 table using &lt;/SPAN&gt;&lt;SPAN&gt;dlt.apply_changes_from_snapshot()&lt;/SPAN&gt;&lt;SPAN&gt;.&lt;/SPAN&gt;&lt;/P&gt;&lt;P class=""&gt;&lt;SPAN&gt;Conceptually it looks like this:&lt;/SPAN&gt;&lt;/P&gt;&lt;P class=""&gt;&lt;SPAN&gt;&lt;a href="https://community.databricks.com/t5/user/viewprofilepage/user-id/97035"&gt;@Dlt&lt;/a&gt;.table def contact():&lt;BR /&gt;return spark.readStream.table("raw.contact")&lt;BR /&gt;&lt;BR /&gt;dlt.apply_changes_from_snapshot( target="contact_scd2", source="contact", keys=&lt;SPAN class=""&gt;["Id"]&lt;/SPAN&gt;, stored_as_scd_type=2 )&lt;/SPAN&gt;&lt;/P&gt;&lt;P class=""&gt;&lt;STRONG&gt;&lt;SPAN&gt;Important:&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;SPAN&gt; We are &lt;/SPAN&gt;&lt;STRONG&gt;&lt;SPAN&gt;NOT&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;SPAN&gt; performing a Full Refresh on the SCD2 pipeline.&lt;/SPAN&gt;&lt;/P&gt;&lt;H3&gt;&lt;SPAN&gt;My questions&lt;/SPAN&gt;&lt;/H3&gt;&lt;OL&gt;&lt;LI&gt;&lt;SPAN&gt;Is this architecture officially supported?&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN&gt;Will &lt;/SPAN&gt;&lt;SPAN&gt;apply_changes_from_snapshot()&lt;/SPAN&gt;&lt;SPAN&gt; correctly detect deleted records and close the corresponding SCD2 records after the full refresh?&lt;/SPAN&gt;&lt;/LI&gt;&lt;LI&gt;&lt;SPAN&gt;Is there any risk of checkpoint corruption or inconsistent state in the SCD2 pipeline because the upstream pipeline was fully refreshed?&lt;/SPAN&gt;&lt;/LI&gt;&lt;LI&gt;&lt;SPAN&gt;How are schema changes handled (especially when a column is removed from the source)?&lt;/SPAN&gt;&lt;/LI&gt;&lt;/OL&gt;&lt;P class=""&gt;&lt;SPAN&gt;I've read the documentation for Full Refresh and &lt;/SPAN&gt;&lt;SPAN&gt;apply_changes_from_snapshot()&lt;/SPAN&gt;&lt;SPAN&gt;, but I couldn't find guidance on this specific scenario where an upstream snapshot pipeline is fully refreshed while the downstream SCD2 pipeline continues incrementally.&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN&gt;Any insight from the Databricks team or anyone with production experience would be greatly appreciated.&lt;/SPAN&gt;&lt;/P&gt;</description>
    <pubDate>Fri, 24 Jul 2026 18:42:43 GMT</pubDate>
    <dc:creator>lausikh</dc:creator>
    <dc:date>2026-07-24T18:42:43Z</dc:date>
    <item>
      <title>What happens to with SCD2 tables if the source pipeline performs a Full Refresh?</title>
      <link>https://community.databricks.com/t5/data-engineering/what-happens-to-with-scd2-tables-if-the-source-pipeline-performs/m-p/164066#M55221</link>
      <description>&lt;P class=""&gt;&lt;SPAN&gt;Hi everyone,&lt;/SPAN&gt;&lt;/P&gt;&lt;P class=""&gt;&lt;SPAN&gt;I'm looking for clarification on how Lakeflow/DLT behaves in the following scenario.&lt;/SPAN&gt;&lt;/P&gt;&lt;P class=""&gt;&lt;SPAN&gt;We have two independent pipelines:&lt;/SPAN&gt;&lt;/P&gt;&lt;P class=""&gt;&lt;STRONG&gt;&lt;SPAN&gt;Pipeline 1 (Ingestion)&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;/P&gt;&lt;UL&gt;&lt;LI&gt;&lt;SPAN&gt;Ingests Salesforce objects into Delta tables.&lt;/SPAN&gt;&lt;/LI&gt;&lt;LI&gt;&lt;SPAN&gt;These tables represent the current snapshot of Salesforce.&lt;/SPAN&gt;&lt;/LI&gt;&lt;LI&gt;&lt;SPAN&gt;Once a week, we plan to run this pipeline with &lt;/SPAN&gt;&lt;STRONG&gt;&lt;SPAN&gt;Full Refresh&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;SPAN&gt; (&lt;/SPAN&gt;&lt;SPAN&gt;full_refresh: true&lt;/SPAN&gt;&lt;SPAN&gt;) because records and columns are sometimes deleted in Salesforce, and incremental ingestion doesn't always reflect those deletions.&lt;/SPAN&gt;&lt;/LI&gt;&lt;/UL&gt;&lt;P class=""&gt;&lt;STRONG&gt;&lt;SPAN&gt;Pipeline 2 (SCD2)&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;/P&gt;&lt;P class=""&gt;&lt;SPAN&gt;For each ingested table, we have a separate pipeline that creates an SCD2 table using &lt;/SPAN&gt;&lt;SPAN&gt;dlt.apply_changes_from_snapshot()&lt;/SPAN&gt;&lt;SPAN&gt;.&lt;/SPAN&gt;&lt;/P&gt;&lt;P class=""&gt;&lt;SPAN&gt;Conceptually it looks like this:&lt;/SPAN&gt;&lt;/P&gt;&lt;P class=""&gt;&lt;SPAN&gt;&lt;a href="https://community.databricks.com/t5/user/viewprofilepage/user-id/97035"&gt;@Dlt&lt;/a&gt;.table def contact():&lt;BR /&gt;return spark.readStream.table("raw.contact")&lt;BR /&gt;&lt;BR /&gt;dlt.apply_changes_from_snapshot( target="contact_scd2", source="contact", keys=&lt;SPAN class=""&gt;["Id"]&lt;/SPAN&gt;, stored_as_scd_type=2 )&lt;/SPAN&gt;&lt;/P&gt;&lt;P class=""&gt;&lt;STRONG&gt;&lt;SPAN&gt;Important:&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;SPAN&gt; We are &lt;/SPAN&gt;&lt;STRONG&gt;&lt;SPAN&gt;NOT&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;SPAN&gt; performing a Full Refresh on the SCD2 pipeline.&lt;/SPAN&gt;&lt;/P&gt;&lt;H3&gt;&lt;SPAN&gt;My questions&lt;/SPAN&gt;&lt;/H3&gt;&lt;OL&gt;&lt;LI&gt;&lt;SPAN&gt;Is this architecture officially supported?&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN&gt;Will &lt;/SPAN&gt;&lt;SPAN&gt;apply_changes_from_snapshot()&lt;/SPAN&gt;&lt;SPAN&gt; correctly detect deleted records and close the corresponding SCD2 records after the full refresh?&lt;/SPAN&gt;&lt;/LI&gt;&lt;LI&gt;&lt;SPAN&gt;Is there any risk of checkpoint corruption or inconsistent state in the SCD2 pipeline because the upstream pipeline was fully refreshed?&lt;/SPAN&gt;&lt;/LI&gt;&lt;LI&gt;&lt;SPAN&gt;How are schema changes handled (especially when a column is removed from the source)?&lt;/SPAN&gt;&lt;/LI&gt;&lt;/OL&gt;&lt;P class=""&gt;&lt;SPAN&gt;I've read the documentation for Full Refresh and &lt;/SPAN&gt;&lt;SPAN&gt;apply_changes_from_snapshot()&lt;/SPAN&gt;&lt;SPAN&gt;, but I couldn't find guidance on this specific scenario where an upstream snapshot pipeline is fully refreshed while the downstream SCD2 pipeline continues incrementally.&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN&gt;Any insight from the Databricks team or anyone with production experience would be greatly appreciated.&lt;/SPAN&gt;&lt;/P&gt;</description>
      <pubDate>Fri, 24 Jul 2026 18:42:43 GMT</pubDate>
      <guid>https://community.databricks.com/t5/data-engineering/what-happens-to-with-scd2-tables-if-the-source-pipeline-performs/m-p/164066#M55221</guid>
      <dc:creator>lausikh</dc:creator>
      <dc:date>2026-07-24T18:42:43Z</dc:date>
    </item>
    <item>
      <title>Re: What happens to with SCD2 tables if the source pipeline performs a Full Refresh?</title>
      <link>https://community.databricks.com/t5/data-engineering/what-happens-to-with-scd2-tables-if-the-source-pipeline-performs/m-p/164608#M55301</link>
      <description>&lt;P&gt;The concept is supported — but there's one detail in your code that's likely the real risk, and it's not the full refresh itself.&lt;/P&gt;&lt;P&gt;1. Deletion detection: yes, that's literally what the API is designed for. AUTO CDC FROM SNAPSHOT (the new name for apply_changes_from_snapshot — same signature, Databricks recommends renaming) compares consecutive snapshots and infers inserts, updates and deletes; keys present in the target but gone from the source get deleted — which for SCD2 means the record is closed with an end date. So your weekly full refresh surfacing Salesforce deletions is exactly the use case.&lt;/P&gt;&lt;P&gt;2. Here's my concern: your code wraps the source in spark.readStream.table("raw.contact") and feeds THAT to the snapshot API. A streaming read on a table that gets fully rewritten once a week is where checkpoint pain lives — streaming reads error out when existing records change or disappear underneath them. The snapshot API doesn't want a stream at all: in periodic snapshot mode you pass the source as a plain table name (source="raw.contact"), and each pipeline update it reads the current state of that table and diffs it against the target. No streaming checkpoint on the source, so an upstream full refresh is just "the next snapshot" — which is the whole point. I'd drop the intermediate streaming table and pass the name directly. And you're right NOT to full-refresh the SCD2 pipeline — that would rebuild it from the current snapshot only and wipe your history.&lt;/P&gt;&lt;P&gt;3. Schema changes: this is the honest gap. New columns generally flow through, but I couldn't find documentation describing what happens when a column is REMOVED from the source for this specific API — so I won't guess. I'd test column removal in a dev pipeline before trusting it, or protect yourself with an explicit select of the columns you track so source drift doesn't surprise the target.&lt;/P&gt;&lt;P&gt;One small design note: since deletions only become visible at the weekly full refresh, your SCD2 end dates for deleted records will be accurate to the week, not the day. If that's fine for your consumers, great — just worth stating explicitly.&lt;BR /&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;/P&gt;</description>
      <pubDate>Fri, 31 Jul 2026 10:56:28 GMT</pubDate>
      <guid>https://community.databricks.com/t5/data-engineering/what-happens-to-with-scd2-tables-if-the-source-pipeline-performs/m-p/164608#M55301</guid>
      <dc:creator>ThomazNeto</dc:creator>
      <dc:date>2026-07-31T10:56:28Z</dc:date>
    </item>
    <item>
      <title>Re: What happens to with SCD2 tables if the source pipeline performs a Full Refresh?</title>
      <link>https://community.databricks.com/t5/data-engineering/what-happens-to-with-scd2-tables-if-the-source-pipeline-performs/m-p/164621#M55303</link>
      <description>&lt;P data-pm-slice="1 1 []"&gt;The pattern is documented and you are right not to full refresh pipeline 2, but as written the deletion detection can never fire, and the full refresh is not why.&lt;/P&gt;
&lt;P&gt;&lt;CODE&gt;spark.readStream.table("raw.contact")&lt;/CODE&gt; makes &lt;CODE&gt;contact&lt;/CODE&gt; append-only, so no key ever leaves it, and the API closes a record only when a key present in the target is "no longer present in the source." That read also fails outright on any update or delete to the source, which an ordinary sync produces, so &lt;CODE&gt;skipChangeCommits&lt;/CODE&gt; would only hide the failure and the deletes with it.&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;
&lt;P&gt;&lt;STRONG&gt;Give the API a batch snapshot instead of a stream.&lt;/STRONG&gt; The documented pattern is a &lt;CODE&gt;&lt;a href="https://community.databricks.com/t5/user/viewprofilepage/user-id/25059"&gt;@DP&lt;/a&gt;.view&lt;/CODE&gt; returning &lt;CODE&gt;spark.read.table("raw.contact")&lt;/CODE&gt;, then &lt;CODE&gt;dp.create_streaming_table("contact_scd2")&lt;/CODE&gt; and &lt;CODE&gt;dp.create_auto_cdc_from_snapshot_flow(target="contact_scd2", source="&amp;lt;that view&amp;gt;", keys=["Id"], stored_as_scd_type=2)&lt;/CODE&gt;. (&lt;CODE&gt;apply_changes_from_snapshot&lt;/CODE&gt; is the old name for the same function.) With no checkpoint on the source, the weekly refresh is just the next snapshot and deletes close the SCD2 rows. Try it in a dev pipeline first, since changing the source a flow reads can require a full refresh.&lt;/P&gt;
&lt;/LI&gt;
&lt;LI&gt;
&lt;P&gt;&lt;STRONG&gt;Run pipeline 2 as a task after pipeline 1 in one job.&lt;/STRONG&gt; A refresh that fails partway is documented to leave target tables "in an inconsistent state with partial data," and a snapshot read against a half-loaded table end-dates every key it cannot see. Nothing flags that for you either, since the snapshot API does not emit &lt;CODE&gt;num_deleted_rows&lt;/CODE&gt;. A row-count expectation on the view is cheap insurance, and &lt;CODE&gt;pipelines.reset.allowed = false&lt;/CODE&gt; on the target stops anyone refreshing the history away.&lt;/P&gt;
&lt;/LI&gt;
&lt;LI&gt;
&lt;P&gt;&lt;STRONG&gt;A removed column never reaches your SCD2 table.&lt;/STRONG&gt; The connector marks it inactive rather than dropping it, so &lt;CODE&gt;raw.contact&lt;/CODE&gt; keeps its schema. Type changes are the ones it cannot handle.&lt;/P&gt;
&lt;/LI&gt;
&lt;/OL&gt;
&lt;P&gt;Worth questioning the weekly refresh itself, though: soft deletes land on the next sync and deleted columns are handled automatically, so the only cases documented as needing a full refresh are true hard deletes and records purged from the recycle bin before the next sync.&lt;/P&gt;</description>
      <pubDate>Fri, 31 Jul 2026 14:32:07 GMT</pubDate>
      <guid>https://community.databricks.com/t5/data-engineering/what-happens-to-with-scd2-tables-if-the-source-pipeline-performs/m-p/164621#M55303</guid>
      <dc:creator>AbhilashNagilla</dc:creator>
      <dc:date>2026-07-31T14:32:07Z</dc:date>
    </item>
    <item>
      <title>Re: What happens to with SCD2 tables if the source pipeline performs a Full Refresh?</title>
      <link>https://community.databricks.com/t5/data-engineering/what-happens-to-with-scd2-tables-if-the-source-pipeline-performs/m-p/164679#M55314</link>
      <description>&lt;P&gt;This is the definitive answer for this thread — and a sharper diagnosis than mine. I'd flagged the readStream intermediate as where the checkpoint risk lives, but your point is stronger: it doesn't just risk breaking, it makes deletion detection structurally impossible, since an append-only intermediate never loses a key. That's a subtle failure mode because everything *looks* healthy while silently never closing a record.&lt;/P&gt;&lt;P&gt;The partial-load scenario in your point 2 is the one I'd underline for anyone finding this later: a snapshot read against a half-loaded source end-dates every key it can't see, with no signal. Orchestrating both as tasks in one job + a row-count expectation on the view is cheap insurance against an expensive, quiet data corruption.&lt;/P&gt;&lt;P&gt;One small clarification if you have a moment: is passing the source table name directly as a string to create_auto_cdc_from_snapshot_flow also supported, or is the &lt;a href="https://community.databricks.com/t5/user/viewprofilepage/user-id/25059"&gt;@DP&lt;/a&gt;.view wrapper the required/recommended shape? Asking because the string form shows up in older examples and it'd be good to know if it behaves identically.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Sun, 02 Aug 2026 10:29:45 GMT</pubDate>
      <guid>https://community.databricks.com/t5/data-engineering/what-happens-to-with-scd2-tables-if-the-source-pipeline-performs/m-p/164679#M55314</guid>
      <dc:creator>ThomazNeto</dc:creator>
      <dc:date>2026-08-02T10:29:45Z</dc:date>
    </item>
  </channel>
</rss>

