mafw.db.migration.runtime
Runtime helpers used by generated migration scripts.
Generated migration scripts import from this module so that the script body
stays compact and readable for a reviewing scientist. The helpers wrap the
small amount of playhouse.migrate and peewee boilerplate needed to
create a new table or add a nullable column, which are the additive operations
the differ currently supports.
They also expose temporary_trigger_removal() (a context manager, and its
underlying remove_all_triggers() / restore_all_triggers()
primitives), which a reviewed destructive migration should bracket its
operations with on SQLite. Several ALTER-limited backends (SQLite in
particular) implement a column drop/rename/type change by rebuilding the table
(create a temporary table, copy the data, drop the original, rename the temporary
one). The backend refuses to drop the original table while a trigger still points
at it, and MAFw triggers are a MAFw extension that playhouse.migrate knows
nothing about. Dropping every MAFw trigger before the operations and recreating
them afterwards removes that clash; this is exactly what
TriggerRefresher does, so it is safe. The
context manager restores the triggers in a finally clause, so they are never
left dropped even if the migration body raises.
Added in version 2.4.
- author:
Bulgheroni Antonio (antonio.bulgheroni@ec.europa.eu)
Functions
|
Create a table for a model by resolving it from the model register. |
|
Build a nullable peewee field of the requested logical type. |
|
Drop every database trigger and return the affected |
|
Recreate every MAFw trigger after a destructive migration. |
|
Context manager that drops MAFw triggers for the duration of a migration. |
- mafw.db.migration.runtime._trigger_dialect(database: Database) TriggerDialect[source]
Return the MAFw trigger dialect for the live database.
- Parameters:
database (peewee.Database) – The live database (possibly a proxy).
- Returns:
The matching trigger dialect.
- Return type:
- Raises:
UnsupportedDatabaseError – for an unsupported backend.
- mafw.db.migration.runtime._unwrap(database: Database) Database[source]
Return the concrete database, unwrapping a proxy when necessary.
- Parameters:
database (peewee.Database) – The database or proxy to unwrap.
- Returns:
The concrete database instance.
- Return type:
peewee.Database
- mafw.db.migration.runtime.create_table(database: Database, table_name: str) None[source]
Create a table for a model by resolving it from the model register.
The table is created with
safe=Trueso that an already-existing table (for example one created byTableCreator) is not an error.- Parameters:
database (peewee.Database) – The live database the migration runs against.
table_name (str) – The name of the table to create.
- mafw.db.migration.runtime.nullable_field(field_type: str) Field[source]
Build a nullable peewee field of the requested logical type.
- Parameters:
field_type (str) – The peewee
field_typetoken (for exampleVARCHAR).- Returns:
A nullable field instance suitable for
migrator.add_column.- Return type:
peewee.Field
- mafw.db.migration.runtime.remove_all_triggers(database: Database) list[tuple[str, str]][source]
Drop every database trigger and return the affected
(trigger, table)pairs.Call this inside a reviewed destructive migration before the
migrator.migrate(...)operations, and pair it withrestore_all_triggers()afterwards. It removes the clash between a table-rebuild operation (common on SQLite, which refuses to drop a table a trigger points at) and MAFw’s triggers, whichplayhouse.migratedoes not manage. Dropping and recreating MAFw triggers is safe because they are regenerable from the model register, mirroringTriggerRefresher.- Parameters:
database (peewee.Database) – The live database to operate on.
- Returns:
The list of
(trigger_name, table_name)pairs that were dropped.- Return type:
list[tuple[str, str]]
- mafw.db.migration.runtime.restore_all_triggers(database: Database) None[source]
Recreate every MAFw trigger after a destructive migration.
Call this inside a reviewed destructive migration after the
migrator.migrate(...)operations, to recreate the triggers thatremove_all_triggers()dropped. Triggers are recreated by re-running the (idempotent,safe=True) table creation for every registered model, which regenerates the model’s declared triggers viacreate_table()without touching existing data.- Parameters:
database (peewee.Database) – The live database to operate on.
- mafw.db.migration.runtime.temporary_trigger_removal(database: Database) Iterator[list[tuple[str, str]]][source]
Context manager that drops MAFw triggers for the duration of a migration.
Enter drops every database trigger (via
remove_all_triggers()) and yields the dropped(trigger, table)pairs; exit recreates every registered model’s triggers (viarestore_all_triggers()) in afinallyclause, so the triggers are always restored — on normal exit and when the body raises. This is the recommended way to bracket a reviewed destructive migration on anALTER-limited backend (SQLite), where a table rebuild fails while a trigger still points at the table.Note
The MAFw applier runs the whole migration inside a single
database.atomic()on transactional backends (SQLite, PostgreSQL); the per-operationplayhouse.migraterunner does not open its own transaction. On those backends a failure therefore rolls back the trigger drops together with the schema change, and this context manager’sfinallyrecreation runs within the same (about-to-roll-back) transaction, which is harmless. On a non-transactional backend (MySQL) thefinallyrecreation is what actually guarantees the triggers are not left dropped after a mid-migration failure.Example inside a generated migration script:
def migrate(migrator, database): operations = [migrator.drop_column('widget', 'gone')] with temporary_trigger_removal(database): migrator.migrate(*operations)
- Parameters:
database (peewee.Database) – The live database to operate on.
- Returns:
A context manager yielding the list of dropped
(trigger, table)pairs.- Return type:
Iterator[list[tuple[str, str]]]
- mafw.db.migration.runtime._FIELD_FACTORIES: dict[str, type[Field]] = {'AUTO': <class 'peewee.IntegerField'>, 'BIGINT': <class 'peewee.BigIntegerField'>, 'BLOB': <class 'peewee.BlobField'>, 'BOOL': <class 'peewee.BooleanField'>, 'CHAR': <class 'peewee.CharField'>, 'DATE': <class 'peewee.DateField'>, 'DATETIME': <class 'peewee.DateTimeField'>, 'DECIMAL': <class 'peewee.DecimalField'>, 'DOUBLE': <class 'peewee.DoubleField'>, 'FLOAT': <class 'peewee.FloatField'>, 'INT': <class 'peewee.IntegerField'>, 'REAL': <class 'peewee.FloatField'>, 'SMALLINT': <class 'peewee.SmallIntegerField'>, 'TEXT': <class 'peewee.TextField'>, 'TIME': <class 'peewee.TimeField'>, 'VARCHAR': <class 'peewee.CharField'>}
Mapping from the peewee
field_typetoken to a nullable field factory. Only the common additive types are mapped; unknown types fall back to a nullablepeewee.TextField.