mafw.db.migration.script
Migration-script representation, naming, rendering and safe writing.
A migration script is a reviewable, editable Python module generated by the
service for one supported schema diff. It declares its version identifier, a
human-readable summary of the detected change, a content checksum, and the
ordered list of playhouse.migrate operations to run inside a
migrate(migrator, database) function.
The file stem is a pure, deterministic function of the version component and a short stable digest of the canonicalised diff: the same diff yields the same name, and distinct diffs within a directory yield distinct names. Generation never overwrites an existing file, so a scientist can edit a generated script and have the edited content applied verbatim.
Added in version 2.4.
- author:
Bulgheroni Antonio (antonio.bulgheroni@ec.europa.eu)
Functions
|
Return the sha-256 checksum of a script body, ignoring the checksum line. |
|
Return a short stable digest of the canonicalised diff. |
|
Parse a migration script descriptor from a file on disk. |
|
Return the checksum recorded in a script header, if present. |
|
Render an editable migration-script module for a diff. |
|
Compute the deterministic, injective file stem for a migration script. |
|
Write a migration script, refusing to overwrite an existing file. |
Classes
|
A generated or discovered migration script. |
- class mafw.db.migration.script.MigrationScript(version: str, name: str, path: Path, checksum: str, requires_review: bool = False)[source]
Bases:
objectA generated or discovered migration script.
- Parameters:
version (str) – The sortable version identifier (for example a zero-padded sequence number).
name (str) – The file stem, deterministic from the diff.
path (Path) – The absolute path of the script on disk.
checksum (str) – The sha-256 checksum of the canonical script content.
requires_review (bool) – Whether the script still carries a pending review-required flag for one or more unsupported/destructive operations. A script that requires review is refused by the applier until a scientist has inspected it and cleared the flag.
Added in version 2.4.
- mafw.db.migration.script._operation_lines(diff: SchemaDiff) list[str][source]
Render the ordered operation statements for the supported differences.
Only the supported (safe, additive) differences are emitted as executable operations. Unsupported/destructive differences are rendered separately as commented, non-executing stubs by
_review_lines().- Parameters:
diff (SchemaDiff) – The schema diff whose supported differences are rendered.
- Returns:
The list of Python source lines inside the
migratefunction.- Return type:
list[str]
- mafw.db.migration.script._review_lines(diff: SchemaDiff) list[str][source]
Render commented stubs for the unsupported/destructive differences.
Each unsupported difference becomes a loud, non-executing comment block that states the detected change, the data-loss risk, and a suggested (commented)
playhouse.migratecall. The scientist must complete and uncomment the operation by hand, then clear__migration_requires_review__to apply it.- Parameters:
diff (SchemaDiff) – The schema diff whose unsupported differences are rendered.
- Returns:
The list of Python source lines inside the review section.
- Return type:
list[str]
- mafw.db.migration.script.content_checksum(body: str) str[source]
Return the sha-256 checksum of a script body, ignoring the checksum line.
The checksum covers the canonical content of the file so that an unrelated change to the recorded checksum line cannot mask a real content change.
- Parameters:
body (str) – The full script body.
- Returns:
The sha-256 hexadecimal digest of the canonical content.
- Return type:
str
- mafw.db.migration.script.diff_digest(diff: SchemaDiff) str[source]
Return a short stable digest of the canonicalised diff.
- Parameters:
diff (SchemaDiff) – The schema diff to digest.
- Returns:
The first twelve hexadecimal characters of the sha-256 digest.
- Return type:
str
- mafw.db.migration.script.load_script(path: Path) MigrationScript[source]
Parse a migration script descriptor from a file on disk.
- Parameters:
path (Path) – The path to the migration script.
- Returns:
The parsed descriptor.
- Return type:
- Raises:
ValueError – if the file lacks a parseable version header.
- mafw.db.migration.script.recorded_checksum(path: Path) str | None[source]
Return the checksum recorded in a script header, if present.
- Parameters:
path (Path) – The path to the migration script.
- Returns:
The recorded checksum, or
Nonewhen absent.- Return type:
str | None
- mafw.db.migration.script.render_script(diff: SchemaDiff, version: str) str[source]
Render an editable migration-script module for a diff.
The generated module declares its version and checksum, documents the change, and exposes a
migrate(migrator, database)function. Supported (safe, additive) differences are emitted as executable operations. If the diff contains any unsupported/destructive difference, the module additionally declares__migration_requires_review__ = Trueand renders a loud, commented review section: the service refuses to apply such a script until a scientist has reviewed it, completed the operations by hand, and cleared the flag. The body is a template a scientist may freely edit before applying.- Parameters:
diff (SchemaDiff) – The schema diff to render.
version (str) – The sortable version component.
- Returns:
The full script body as text.
- Return type:
str
- mafw.db.migration.script.script_name(diff: SchemaDiff, version: str) str[source]
Compute the deterministic, injective file stem for a migration script.
The stem combines the version component with a short stable digest of the canonicalised diff.
script_nameis a pure function: the same diff and version yield the same name, and distinct diffs yield distinct names.- Parameters:
diff (SchemaDiff) – The schema diff the script will carry.
version (str) – The sortable version component.
- Returns:
The file stem (without the
.pyextension).- Return type:
str
- mafw.db.migration.script.write_script(directory: Path, name: str, body: str) MigrationScript[source]
Write a migration script, refusing to overwrite an existing file.
If a file with the target name already exists, its bytes are preserved unchanged and the existing script is returned (parsed from disk). This is what lets a scientist edit a generated script and keep the edited content.
- Parameters:
directory (Path) – The resolved migration directory.
name (str) – The file stem (without extension).
body (str) – The script body to write when the file does not yet exist.
- Returns:
The written or pre-existing migration script descriptor.
- Return type:
- mafw.db.migration.script._MIGRATOR_OPERATIONS: tuple[str, ...] = ('add_column(table, column_name, field, allow_not_null=False)', 'drop_column(table, column_name, cascade=True)', 'rename_column(table, old_name, new_name)', 'add_not_null(table, column)', 'drop_not_null(table, column)', 'add_column_default(table, column, default)', 'drop_column_default(table, column)', 'alter_column_type(table, column, field, cast=None)', 'rename_table(old_name, new_name)', 'add_index(table, columns, unique=False, using=None, where=None, nulls_distinct=None, name=None)', 'drop_index(table, index_name)', 'add_unique(table, *column_names)', 'add_constraint(table, name, constraint)', 'drop_constraint(table, name)', 'add_foreign_key_constraint(table, column_name, rel, rel_column, ...)', 'drop_foreign_key_constraint(table, column_name)', 'drop_table(table, safe=False, cascade=False, schema=None)')
Reference list of the operations offered by the per-backend
playhouse.migrate.SchemaMigrator, embedded verbatim in the docstring of every generated script so a reviewing scientist has the exact signatures to hand while completing a migration. Mirrors the installed Peewee 4.5.3 API and the documentation at https://docs.peewee-orm.com/en/latest/peewee/db_tools.html#module-playhouse.migrate
- mafw.db.migration.script._UNSUPPORTED_HINTS: dict[str, str] = {'add_not_null_column': 'migrator.add_column({table!r}, {column!r}, <field_with_default>) # backfill data first', 'alter_column_type': 'migrator.alter_column_type({table!r}, {column!r}, <new_field>)', 'alter_nullability': 'migrator.add_not_null({table!r}, {column!r}) # or drop_not_null(...)', 'drop_column': 'migrator.drop_column({table!r}, {column!r})', 'drop_index': "migrator.drop_index({table!r}, '<index_name>') # index on ({column})", 'drop_table': 'migrator.drop_table({table!r})'}
Suggested, intentionally non-executing migrator calls for each unsupported difference kind. The scientist must uncomment and complete the operation by hand, because the service never performs a destructive change automatically.
- mafw.db.migration.script._VERSION_RE = re.compile('^__migration_version__\\s*=\\s*[\'\\"](?P<version>[^\'\\"]+)[\'\\"]', re.MULTILINE)
Regular expression used to parse the metadata header of a generated script.