Semaphor
Migrations

Formatting Migration

How your saved number formats, date formats, and highlight rules move to their new layout when you upgrade, and how to preview, check, and roll back the move

Semaphor stores each column's number and date format, and each highlight rule, with the column it applies to. When you upgrade to a version that includes this change (noted in the Release Notes), Semaphor moves the formats and rules on your existing dashboards, library visuals, and semantic models for you, the first time the new version starts. You don't run a script, and your dashboards look the same afterwards.

What happens during the upgrade

  • The migration runs once, when the new version of the API service first starts: after the database schema changes, and before Semaphor starts serving requests.
  • Before it changes anything, Semaphor saves a copy of every dashboard, library visual, and semantic model it reads to your data volume, under /data/backups/card-presentation/.
  • It's all or nothing: either every dashboard moves, or nothing in your database changes.
  • It usually takes a few seconds. A deployment with thousands of dashboards can take a few minutes.

In the API service's startup log you'll see:

Moving saved formats and rules to their new stores (once)...
Card presentation upgrade (apply): {"mode":"apply",...,"written":42,"snapshot":"/data/backups/card-presentation/2026-11-03T15-04-05-123Z",...}

written is the number of dashboards, library visuals, and semantic models the migration updated, and snapshot is the folder that holds the copy it took.

The copy stays on your data volume. Keep it until you've confirmed your dashboards look right; after that you can delete the folder.

Before you upgrade

Back up your database

Take a full backup as described in the Upgrade Guide, for the embedded database or your external one.

Preview the migration (optional)

Pin the new version in docker-compose.yml and pull the images. Then run the preview with the new version:

docker-compose pull
docker-compose stop api-service   # embedded database only
docker-compose run --rm api-service card-presentation-upgrade --dry-run

If you use the embedded database, stop the API service first: two copies of it can't share the database files. With an external database, you can run the preview while Semaphor keeps running.

The preview changes nothing. It prints how many dashboards, library visuals, and semantic models the migration will update, and counts any saved formatting that has no equivalent in the new layout, usually settings that no longer apply to any column. The same summary is saved under /data/backups/card-presentation/<time>-dry-run/. If you'd like us to review it before you upgrade, send the printed summary to your Semaphor contact.

Upgrade

Start the new version as usual:

docker-compose up -d

Check the migration

docker-compose logs api-service | grep -i "card presentation upgrade"

A line that starts with Card presentation upgrade (apply) means the migration completed. Then open a few dashboards whose tables or charts use custom number or date formats or highlight rules.

Later restarts don't run the migration again.

If the migration doesn't complete

Semaphor still starts. The startup log says why, then shows:

WARNING: The card presentation upgrade did not finish; the lines above say whether anything changed.
         The server starts anyway; the next start tries again.

The line above the warning tells you what happened to your data:

  • If it ends with Nothing was written., your database is as it was. Until the migration completes, columns whose formats haven't moved show default formatting.
  • If it says The formats and rules were moved, the migration moved everything but couldn't confirm it. The next start confirms it; nothing else is needed.

To try again, restart the API service:

docker-compose restart api-service

If it doesn't finish on the next start, contact Semaphor support with the log lines from the startup, including the Snapshot: line if one is shown.

Start without the migration

If you need Semaphor running while you look into a migration that didn't complete, you can turn the migration off. Add this to semaphor.env and restart the API service:

SEMAPHOR_SKIP_CARD_PRESENTATION_UPGRADE=true

Columns whose formats haven't moved show default formatting until you remove the setting and restart.

Roll back to your previous version

To go back to the version you upgraded from, put your dashboards back first, while the new version is still installed:

Stop the API service

docker-compose stop api-service

Find the copy the migration took

It's the snapshot folder in the startup log line. You can also list the copies on your data volume:

docker-compose run --rm --entrypoint ls api-service /data/backups/card-presentation

Restore the copy

docker-compose run --rm api-service card-presentation-upgrade --restore /data/backups/card-presentation/<folder>

The restore puts back every dashboard, library visual, and semantic model the migration updated, as long as none has changed since. If one has, it puts back nothing and names it; in that case, restore the full backup you took before upgrading, as described in the Upgrade Guide.

Start your previous version

Set the previous version in docker-compose.yml, then:

docker-compose pull
docker-compose up -d

After a restore, the migration runs again the next time you start a version that includes it.

If you create dashboards through the API

After you upgrade, dashboard templates you save through the API must use the current format settings. A save that still uses an older setting is refused, with an error that names the setting and the one that replaces it.

On this page