Forum Discussion
Incremental Refresh with Deleting Duplicate Records before Appending Staging Data
- 2 years ago
Hello Everyone, thanks for the ideas on this. I've been able to successfully build out an Incremental refresh structure without using a notebook. Some notes on my use case:
- Existing rows in my tables can be updated so I’ll need to delete the old data before appending the new data when pulling in incremental data
- I can’t risk using a notebook for this. I'm using notebooks to push data to an API and can't risk a conflict where the API fails because I'm already running too many notebooks for incremental refreshes.
- Our data sources are mostly on-prem.
- We've subscribed to Fabric capacity (F64)
- I'm a citizen developer and we don't have many data analytics folks who have experience with Data Factory so I'm going to rely more on the citizen dev tools where possible - although learning Data Factory wasn't as hard as I thought it was going to be when they first launched Fabric into Public Preview.
- I'm following the medallion model/architecture though I use names that my users who aren't familiar with bronze/silver/gold would understand - specifically Raw/Cleaned/Refined.
So here's some details on how I've set this up. I'll post additional details.
What I set up:
- Staging Lakehouse - this is needed to copy data from an external source into Fabric (I tried going direct to a Data Warehouse but you can’t – the data needs to be staged)
- Data Warehouse for Raw Data - Only data warehouses support deleting rows in a table using a script so you can’t use a Lakehouse for incremental refresh (unless you use a notebook).
- Data Warehouse for Cleaned Data – For the tables that get cleaned.
- Data Warehouse for the Refined Data - For the tables that are refined.
- Lakehouse - I'm not sure what to call this but really the purpose here is just a repository of links to the tables in the data warehouses. It gives me a layer of abstraction. So when I have someone using a lakehouse in another workspace that needs access to this data, I link to this Lakehouse and if I ever change a table - like if a table needs cleaned that didn't before, I can just update the link in this Lakehouse and I don't need to remember to update any other lakehouses that my users are building against.
Dataflow Gen 2: Admin Table – I start with a Dataflow Gen2 which is just a manual set of tables that I use to iterate over for pulling in data. So that includes these tables and the columns listed:
- Tables to import raw data: Table_Name, Date_Column, Unique_Identifier_Column, Dataflow_Needed*
- Tables to clean: Table_Name, Date_Column, Unique_Identifier_Column
- Tables to refine: Source_Table_Name, Source_Data_Warehouse, Schema, Refined_Table_Name, Date_Column, Unique_Identifier_Column
*This is 1 if the table needs to use a dataflow to copy into the data warehouse instead of a straight copy in Data Factory. I’ve found that long text fields that exceed varchar(8000) need to be copied using a dataflow or custom scripting. Since I’m trying to stay low-code, I’m going with the dataflow gen2 for that. But you could add a column to pull in a script for that specific table if preferred.
A data pipeline manages everything. Here’s what’s in it:
- Lookup Activity: Looks up table in staging lakehouse with the list of tables to import
- ForEach Activity: Iterates over the rows in the list of tables to import
- Script: Grab the max date (value in Date_Column) for the table (value in Table_Name)
- Copy data Activity: Copies the data from the on-prem data source after the max date for the table and copies it to the staging lakehouse. I have this add “staging__” to the front of the table name.
- Script: Delete matching IDs (from the Unique_Identifier_Column) for the table in the Data Warehouse for Raw Data that match the staging table in the staging lakehouse.
- If Condition: Checks to see if the table requires a Dataflow to copy
- If the table does NOT need a dataflow
- Script: Insert data from the staging table in the staging lakehouse into the table in the Data Warehouse for Raw Data
- If the table does need a dataflow then nothing happens – that’s covered in step 3
- If the table does NOT need a dataflow
- Dataflow Gen2: Append staging data from staging lakehouse to the tables in the data warehouse for raw data – this doesn’t do any processing of the data
- Lookup Activity: Looks up table in staging lakehouse with list of tables that need cleaned.
- ForEach Activity: Iterates over the rows in the list of tables to clean
- Script: Grab the max date (value in Date_Column) for the table (value in Table_Name)
- Copy data Activity: Copies the data from the table in the Data Warehouse for raw data after the max date for the table and copies it to the staging lakehouse. I have this add “cleanstaging__” to the front of the table name.
- Script: Delete matching IDs (from the Unique_Identifier_Column) for the table in the Data Warehouse for Cleaned Data that match the staging table in the staging lakehouse.
- Dataflow Gen2: Cleans and Appends data from staging lakehouse (from the version starting with “cleanstaging__” to the tables in the data warehouse for cleaned data – this dataflow does take steps to clean the tables before appending them
- Lookup Activity: Looks up the table in the staging lakehouse with the list of tables that need refined.
- ForEach Activity: Iterates over the rows in the list of tables to clean
- Script: Grab the max date (value in Date_Column) for the table (value in Refined_Table_Name)
- Copy data Activity: Copies the data from the table in the Data Warehouse for cleaned data after the max date for the table and copies it to the staging lakehouse. I have this add “refinestaging__” to the front of the table name.
- Script: Delete matching IDs (from the Unique_Identifier_Column) for the table in the data warehouse for refined data that match the staging table in the staging lakehouse.
- Dataflow Gen2: Refines and Appends data from staging lakehouse (from the version starting with “refinestaging __” to the tables in the data warehouse for refined data – this dataflow does take steps to refine the tables before appending them
There are many nuances so let me know if you have questions. The pattern is pretty simple and basically repeated for each step in the medallion architecture. It would be easy to simplify clean and refining the data. And most of the dataflow gen2 entries could be replaced by SQL scripts if needed/preferred.
Notebooks are easier than all of this. But the limitation on number of notebooks running at one time could cause conflicts with other scheduled notebooks/pipelines (with notebooks) or even with your users who are running ad hoc notebooks.
I've not tried an update statement, I'll explore that!
Hi GregMarbais ,
We haven’t heard from you on the last response and was just checking back to see if you have a resolution yet .
In case if you have any resolution please do share that same with the community as it can be helpful to others .
Otherwise, will respond back with the more details and we will try to help .
- GregMarbais2 years ago
Kudo Collector
Anonymous I think i have a solution but I'm testing it to make sure it does everything I need. The trick (I think) is not using a lakehouse but instead using a Datawarehouse (without a lakehouse). I'm working through it now and will post it as soon as I have a definitive answer. I'm very hopeful!
- Anonymous2 years agoNot applicable
Hi GregMarbais ,
We haven’t heard from you on the last response and was just checking back to see if you have a resolution yet .
In case if you have any resolution please do share that same with the community as it can be helpful to others .
Otherwise, will respond back with the more details and we will try to help .