> ## Documentation Index
> Fetch the complete documentation index at: https://docs.platinur.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Refresh Modes

> Override, Append, and Merge — how each load writes rows.

Each configured source writes into one source schema. The **Refresh mode** (chosen on the source's Config tab, above the table list) controls how Platinur writes rows into that schema. Modes apply per source and, for Append and Merge, resolve **per table**.

## Override

Labeled **Override** in the portal (internal mode `replace`). It overwrites destination tables on every successful load.

Use it for small sources, development sources, or sources where a full reload is expected. Treat it as destructive.

## Append

Labeled **Append** (internal mode `append`). It inserts new rows since the last run and never updates existing rows, using a per-table cursor column. The schema scan suggests a cursor for each table — it looks for temporal columns named like `updated_at`, `last_update`, `last_modified`, or `timestamp` (creation columns like `created_at` when no update column exists); the suggestion is seeded into the source so you can confirm, edit, or clear it. A table with a confirmed cursor appends incrementally on that column; a table with a blank cursor is fully overridden each run.

**The first Append run for a table is a full refresh.** With no cursor watermark recorded yet, appending would duplicate every row the table already holds (for example after a prior Override run) — so the first run replaces the table once while recording the cursor's high-water mark; from the second run onward only new rows are appended. The run log states this explicitly ("first run: full refresh to set the cursor").

Use it for append-only event or transaction streams where records are never updated after they are written.

## Merge

Labeled **Merge** (internal mode `merge`). It upserts changed rows in place by primary key, so sources whose rows mutate after insert stay correct without a full reload. Merge needs two things per table:

* a **cursor column** (as for append) to pull the rows that changed since the last run, and
* a **primary key** to match and replace existing rows.

Scan captures each table's real primary-key constraint from the source database and seeds it onto the source; it is shown per table and can be overridden. On ClickHouse a merge runs as a delete-insert (the matched rows are replaced), so re-running a merge does not duplicate rows the way append would.

Merge resolves per table with a deterministic fallback ladder:

* **cursor + primary key** → merge (upsert changed rows by primary key).
* **cursor but no primary key** → falls back to append.
* **no cursor** → falls back to override (full refresh) of that table.

The run summary reports what actually happened when tables fall back, for example: `3 merged, 1 appended (no primary key), 1 replaced (no cursor)`.

## File sources

CSV and Excel sources are **Override-only** — each run replaces the file tables. Append and Merge
apply to PostgreSQL and MySQL sources.

## Operator checks

* A schema scan is required before **any** run (the Run button stays disabled until one succeeds); for Append and Merge it is also what discovers the cursors and primary keys.
* Confirm the cursor field (and, for merge, the detected primary key) before saving or running the source.
* Watch Monitoring after the first run; the run summary shows the per-table merge/append/replace breakdown.
* Take a backup before changing load modes on production data.

<Note>
  Sources configured before Merge existed may carry the legacy mode name `incremental` — it is
  treated as **Append** (never Merge, which would silently change load semantics).
</Note>
