migrations
Migration for scan_metadata v1 -> v2: normalise scan_datetime.
A data migration, not a schema one — v2's ORM is column-for-column v1's, so
there is no DDL here and gen_migration would render an empty body. What
changes is the column's contents.
v1 stored whatever the vendor path handed over, stringified and unparsed
(bitfount.cache.types.scan_metadata.timestamps has the full account), so one
column held ISO-8601, DICOM DT and DICOM DA values side by side and could
neither be sorted as text nor compared as time without detecting each row's
format first. This hop rewrites every row into the one spelling
normalise_scan_datetime produces.
Why a migration rather than letting the writer converge the column.
scan_metadata re-parses a file only when its content hash changes
(bitfount.runtimes.scan_metadata.tasks), so an unchanged file's row is never
rewritten. Without this hop a customer's existing rows would keep their old
spellings indefinitely, and the column would stay uncomparable for exactly the
datasources that have been running longest.
No downgrade. The normalisation is lossy in two directions a reverse hop
could not undo: a value that would not parse is cleared to NULL, and a DICOM DA
gains a midnight time it did not carry. v2 is v1's ORM — the version package
re-exports it — so a cache rolled back to an older SDK reads these rows without
complaint; the values are simply already normalised.
Module
Functions
upgrade
def upgrade(op: Operations) ‑> None:Rewrite every scan_datetime into ISO-8601 UTC (see the module docstring).
Idempotent: a row already in the target spelling normalises to itself and is not rewritten, so replaying the hop by hand is safe.
Arguments
op: The bound Alembic operations handle; its connection is the one the caller's per-hop transaction runs in, so the rewrite commits or rolls back with the version bump.