Full loading
Full loading is the act of fully reloading the data of your tables. All existing data will be removed and replaced by whatever the source produced on this run. Resources that are not selected while performing a full load will not replace any data in the destination.
Performing a full load
To perform a full load on one or more of your resources, choose the write_disposition='replace' for this resource:
p = dlt.pipeline(destination="bigquery", dataset_name="github")
issues = []
reactions = ["%2B1", "-1", "smile", "tada", "thinking_face", "heart", "rocket", "eyes"]
headers: dict[str, str] = {}
repo_name = "dlt-hub/dlt"
for reaction in reactions:
for page_no in range(1, 3):
page = requests.get(f"https://api.github.com/repos/{repo_name}/issues?state=all&sort=reactions-{reaction}&per_page=100&page={page_no}", headers=headers)
print(f"Got page for {reaction} page {page_no}, requests left", page.headers["x-ratelimit-remaining"])
issues.extend(page.json())
p.run(issues, write_disposition="replace", primary_key="id", table_name="issues")
All tables that belong to a replace resource are truncated on each load, including nested tables and tables created by
dispatching to many tables or as table variants.
Note that a table does not need to receive any data to get truncated.
Replace with incremental loading
The shorthand and the dictionary form of the replace write disposition handle the resource state differently:
- The shorthand
write_disposition="replace"resets the resource state on each run. An incremental on such a resource starts from itsinitial_valueagain, and dlt reloads the table from scratch. - The dictionary form
write_disposition={"disposition": "replace"}keeps the resource state by default. The incremental continues from the last saved cursor and extracts only the new or changed records. The table holds only these records, which is useful when a downstream tool merges them.
The exclude_resource_state option of the dictionary form defaults to True, so these two resources behave the same:
@dlt.resource(write_disposition={"disposition": "replace"})
def clients(updated_at=dlt.sources.incremental("updated_at")):
...
@dlt.resource(write_disposition={"disposition": "replace", "exclude_resource_state": True})
def clients_explicit(updated_at=dlt.sources.incremental("updated_at")):
...
Set exclude_resource_state to False to reset the state like the shorthand does. A run that yields no records truncates the table, so the table can be empty. For an explicit full refresh, use the refresh option instead.
Choosing the correct replace strategy for your full load
dlt implements three different strategies for doing a full load on your table: truncate-and-insert, insert-from-staging, and staging-optimized. The exact behavior of these strategies can also vary between the available destinations.
You can select a strategy with a setting in your config.toml file. If you do not select a strategy, dlt will default to truncate-and-insert.
[destination]
# Set the optimized replace strategy
replace_strategy = "staging-optimized"