> ## Documentation Index
> Fetch the complete documentation index at: https://domoinc-bradley-turek-pfilter-operators-reference.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Creating a Recursive/Snapshot DataFlow in Magic ETL

## Intro

A "recursive" or "snapshot" DataFlow is a DataFlow that uses itself as an input.

DataFlows (both SQL and Magic ETL) cannot append data natively like Connectors. However, if you need to create a DataFlow that appends data, you can do so by running it once and then using the output as part of the input for the next run. By doing this, every time the DataFlow runs, it includes the data from before and also appends the new data onto itself.

<Warning>**Important:** There are significant behavioral differences in Magic ETL. Read the [Behavior Changes and Feature Updates in Magic ETL](/s/article/360047787514) article before converting mission-critical Magic ETL DataFlows. \*\* Failure to do so may cause an unintended change to your DataFlow's behavior.\*\*</Warning>

**Video - What is a Recursive DataFlow?**

<iframe allowfullscreen="allowfullscreen" frameborder="0" height="315" src="//www.youtube-nocookie.com/embed/VkM5VznEzi8" width="560" />

<Warning>**Important:** If a recursive DataFlow is edited incorrectly, you could lose ALL historical data. To avoid this any time you are editing, create an additional DataSet that is a copy of your historical DataSet. This DataSet will remain static. If anything happens to your historical DataSet, you will have a backup from before you began editing.</Warning>

### To create a recursive DataFlow in Magic ETL:

1. Create and run a Magic ETL DataFlow. <img alt="1.png" src="https://mintcdn.com/domoinc-bradley-turek-pfilter-operators-reference/mmKMebN1gzplntwg/images/kb/0EM5w000005vOu3.png?fit=max&auto=format&n=mmKMebN1gzplntwg&q=85&s=72f94bbb2639c6fbb0fe42e2acc473e8" style={{width: 20, height: 20, display: 'inline', verticalAlign: 'start', margin: '0'}} width="974" height="592" data-path="images/kb/0EM5w000005vOu3.png" /> 2. Once the DataFlow has finished running, load the output DataSet as an input DataSet.\
   The Output tile will show the output DataSet name followed by "1." <img alt="2.png" src="https://mintcdn.com/domoinc-bradley-turek-pfilter-operators-reference/mmKMebN1gzplntwg/images/kb/0EM5w000005vOu5.png?fit=max&auto=format&n=mmKMebN1gzplntwg&q=85&s=c12a23f610b841d6a31f5751f087b471" style={{width: 20, height: 20, display: 'inline', verticalAlign: 'start', margin: '0'}} width="1006" height="584" data-path="images/kb/0EM5w000005vOu5.png" /> You should now have two DataSets in the DataFlow—the updating original DataSet and the historical DataSet.\
   You now need to find a column to use as a constraint. This helps determine when to replace data in your historical DataSet with new data. Constraint columns are normally ID columns or date columns or have other unique identifiers. In this example, we use the `Date` column as a constraint.
2. Use **Select Columns** to select only the constraint column. <img alt="step3.png" src="https://mintcdn.com/domoinc-bradley-turek-pfilter-operators-reference/mmKMebN1gzplntwg/images/kb/0EM5w000005vOu9.png?fit=max&auto=format&n=mmKMebN1gzplntwg&q=85&s=4c7d9bbf5e114de48734ef1d48284e9a" style={{width: 20, height: 20, display: 'inline', verticalAlign: 'start', margin: '0'}} width="821" height="632" data-path="images/kb/0EM5w000005vOu9.png" /> 4. Use **Remove Duplicates** to return a unique list of constraints.

<img alt="7.png" src="https://mintcdn.com/domoinc-bradley-turek-pfilter-operators-reference/mmKMebN1gzplntwg/images/kb/0EM5w000005vOuC.png?fit=max&auto=format&n=mmKMebN1gzplntwg&q=85&s=a17b170ede251af80a077e251d8acb8e" style={{width: 20, height: 20, display: 'inline', verticalAlign: 'start', margin: '0'}} width="809" height="227" data-path="images/kb/0EM5w000005vOuC.png" /> 6. Filter any rows from your DataSet where the new date column is not null.\
This returns only rows from the historical DataSet that do not exist in the new updating DataSet. You can do this by adding a Filter Rule or by adding a Formula Rule as shown in the examples below. <img alt="step6.png" src="https://mintcdn.com/domoinc-bradley-turek-pfilter-operators-reference/mmKMebN1gzplntwg/images/kb/0EM5w000005vOtp.png?fit=max&auto=format&n=mmKMebN1gzplntwg&q=85&s=d0eaef82d14b9ba3b03ce903d6dc1847" style={{width: 20, height: 20, display: 'inline', verticalAlign: 'start', margin: '0'}} width="885" height="339" data-path="images/kb/0EM5w000005vOtp.png" /> **Add Filter Rule:**\
Make sure not to forget to choose how you would like the data to be handled if the data types don't match between columns that should be combined. For more information about this option you can find it here under the "Append Rows (Union)" section: [Behavior Changes and Feature Updates in Magic ETL](/s/article/360047787514). <img alt="step8.png" src="https://mintcdn.com/domoinc-bradley-turek-pfilter-operators-reference/mmKMebN1gzplntwg/images/kb/0EM5w000005vOto.png?fit=max&auto=format&n=mmKMebN1gzplntwg&q=85&s=826d34c70886bbfeaf00ccdd4b7e5a70" style={{width: 20, height: 20, display: 'inline', verticalAlign: 'start', margin: '0'}} width="1043" height="815" data-path="images/kb/0EM5w000005vOto.png" /> 9. Connect the **Append** tile to your output. Once complete, your ETL should look like the following:

### Troubleshooting/FAQ

See [DataFlow Troubleshooting](/s/article/360043427953) to see common issues and errors seen when building DataFlows.
