Runs: dry run, batches, recovery, rollback
Before anything is read
Starting a run checks the migration as a whole: the source and its options, the target, that every source field and target exists, no target twice, every transformation exists, lists go to Collections. Nothing runs until that is clean.
Per batch
A run processes Records per batch records (default 50, at most 500) per request:
- read the batch from the source (one or two queries);
- prime every lookup with all values of the batch (one query per kind);
- build each record: source value → transformations → target;
- find the existing objects of the batch (one query);
- load their CAFE values in one go (CAFE bulk loading);
- per record: check every WordPress field and every CAFE value; nothing is written for a record with any problem; then write it in one database transaction (before an update, the old values are stored for rollback);
- save the checkpoint: offset, counts, first 200 problems.
Only one batch is in memory. A lock (an option row that can exist only once) stops two requests from processing the same run; a lock older than ten minutes is released.
Dry run
Exactly the same steps, but step 6 stops after checking. The counts say what would be created, updated, skipped or refused; Written is 0.
Modes and existing data
| Mode | New records | Existing objects |
|---|---|---|
| Create and update | created | updated |
| Only create | created | skipped |
| Only update | skipped | updated |
Only mapped fields change. An empty source value does not clear a saved value unless Empty source values clear saved values is on. Nothing is ever deleted by an import.
A value its CAFE field refuses makes the whole record invalid, so nothing half-written
ends up in CAFE. A migration with skip_invalid_values set (REST, wp cafe migration,
PHP; the ACF → CAFE conversion uses it) leaves such a value out instead, imports the rest
of the record and reports each left-out value as a warning: field left out: why (value: …).
Recovery
When a run stops (closed tab, time limit, server restart), its checkpoint is the last finished batch. Continue it from History or with:
wp cafe migration resume <run-id>
Records of an interrupted batch are imported again; they find the objects they already created (source markers), so nothing is duplicated.
Rollback
Roll back (History → Report, or wp cafe migration rollback <run-id>) works page by
page:
- deletes the posts and terms the run created (their CAFE values go with them),
- puts back the WordPress fields and CAFE values of the objects the run updated, from the values stored just before the change.
What it cannot undo:
- anything in the source: CAFE never writes there;
- edits made to the imported fields after the run: restoring overwrites them;
- files a developer transformation downloaded;
- saved passwords (Password fields) are never copied into backups, so they cannot be restored.
Only the latest import of a migration can be rolled back (roll back newer imports first), and each run once. Dry runs wrote nothing and have nothing to roll back.
History
Every run keeps: migration name, source, start and end, dry run or import, status (running, finished, failed, stopped, rolling back, rolled back), records processed, created, updated, skipped, invalid, warnings, the first 200 problems (download as CSV), the CAFE version and a mapping version (a hash of the mapping, without secrets or file contents). Removing a run from the history keeps what it imported but ends its rollback.
WP-CLI
Best for large migrations, no browser, no request time limit:
wp cafe migration list
wp cafe migration check 12
wp cafe migration run 12 --dry-run
wp cafe migration run 12
wp cafe migration resume 81
wp cafe migration rollback 81 --yes