Advanced

Migrating saved data

A new version reads files written by an old one. That is the part of a release that is hardest to test, because the data is not in the repository and the format change is invisible until someone's file is lost. Migration is a rule per version step, written down before the release.

What you will see

A named drop. An unnamed one is data loss nobody can find later.

About 1 min of reading

Try It

Detect the format.

1

The header

data = {'format': '1.2', 'items': [1,2,3]} print(data['format'])

Before you run it, say out loud what it will print. Then open the answer.

What it prints
The format version on the file itself - the field that makes the loader's choice explicit rather than a guess.
2

The drop report

print('dropped: legacy_colour - no field in v2.0')

Before you run it, say out loud what it will print. Then open the answer.

What it prints
A named drop. An unnamed one is data loss nobody can find later.

Data Flow

An old file becomes a new one.
1 Read the format version
↓
2 Apply the step rules in order
↓
3 Report anything dropped
↓
4 Write the current format
Line by line

Read the first example one line at a time. A line that prints shows what appears on screen; the rest set things up quietly.

data = {'format': '1.2', 'items': [1,2,3]} sets nothing on screen
print(data['format']) The format version on the file itself - the field that makes the loader's choice explicit rather than a guess.
Why this works
Version the file, not only the app

A saved file needs its own format version. Without it, the loader is guessing from shape, and a shape that fits two formats is a file loaded wrongly with no error.

Test with real old files

Keep a file from each past version in the test fixtures. Those files are the only honest test of a loader, and writing a new one instead of keeping an old one tests the wrong thing.

Examples

Read the old, write the new

A loader detects the old format and converts it on read. That keeps every existing file working without touching it, which is safer than a one time rewrite pass over files you cannot enumerate.

One step at a time

A loader that handles 1.0 to 2.0 directly is a guess about every past change. Handling each step in turn composes, and it is the only way a format that changed three times stays readable.

Never lose a field

A field the new format has no place for needs a decision written down: dropped, merged, or kept in an extra slot. A silent drop is a release that deletes data on first open.

Words this lesson uses

Each one is defined here on this site. Open the entry for the full definition and the other words it points at.

← Checking your own versions
Previous Lesson
Checking your own versions
Next Lesson
Dependency ranges and resolution
Dependency ranges and resolution →