Events and Callbacks
Two mechanisms, easy to mix up.
Filename callbacks are SQL (or Python) files in the migrations directory. They run at a named point in migrate / validate / undo / clean. They are not history rows.
-- migrations/beforeMigrate__set_pragma.sql
PRAGMA foreign_keys = ON;-- migrations/afterMigrateError__notify.sql
-- runs only if migrate fails
SELECT 1;See Naming conventions for the nineteen event names and the __ rule.
The Python event bus is for tooling. Every client exposes listeners that receive a typed Event object, never a raw dict.
Subscribing
from dblift.api.events import EventType
def on_script(event):
print(event.event_type.value, event.version, event.execution_time)
client.events.on(EventType.MIGRATION_APPLIED, on_script)
client.events.on("migration.script.*", on_script) # wildcard
client.events.on("*.failed", on_script) # any failure
client.events.off("migration.script.*", on_script)Patterns match on the whole event string, so "*.started" matches migration.started but not migration.started.extra. Either an EventType member or its string value is accepted everywhere.
| EventEmitter method | Behaviour |
|---|---|
on(event, callback) | Register a listener. Accepts an EventType, an exact string, or a wildcard pattern. |
off(event, callback) | Unregister a listener. Silently ignores a callback that was never registered. |
subscribe / unsubscribe | Aliases for on / off, for consumers coming from RxJS, blinker or Node conventions. |
emit(event, data) | Emit an event. data keys must be declared Event fields. |
clear(event=None) | Drop listeners for one event, or all listeners when called with no argument. |
get_history() | Events in dispatch order. Empty unless the emitter was built with keep_history=True. |
clear_history() | Empty the recorded history. |
start_batch() | Collect events instead of dispatching them. |
flush_batch() | Dispatch everything collected so far and keep batching. |
stop_batch() | Leave batch mode and return the collected events. |
The Event payload
A frozen dataclass. event_type and timestamp are always populated and are owned by the emitter — passing either at emit time raises TypeError. Every other field defaults to None; only the subset the dispatching site provides is set, so read defensively.
| Group | Fields |
|---|---|
| Always populated | event_type · timestamp · name |
| Operation context | operation · target_version · dry_run · show_sql · tags · error · result · summary · config · provider · history_manager · log |
| Script level | script · version · description · type · execution_time |
| Generation and undo | dialect · migration_path · count · migrations_applied · results · success_count · failure_count |
The dataclass is the contract
Unknown keyword arguments at emit time raise TypeError rather than being silently dropped. The dataclass is the single source of truth for the event contract, so a new field has to be declared before it can be emitted.
Event catalogue
87 event strings in 11 groups. MIGRATION_SCRIPT_COMPLETED is a backward-compatible alias of MIGRATION_APPLIED — the same enum member, so iterating EventType yields it once.
| Group | Events |
|---|---|
| Migration | migration.started · migration.completed · migration.failed · migration.script.started · migration.script.completed · migration.script.failed · migration.script.skipped · migration.progress · migration.script.validated · migration.script.validation_failed |
| Validation | validation.started · validation.completed · validation.failed · validation.rule.checked · validation.rule.violation · validation.rule.passed |
| Schema and diff | schema.diff.detected · schema.introspection.started · schema.introspection.completed · schema.introspection.failed · schema.object.detected · diff.analysis.started · diff.analysis.completed · script.risk.detected |
| Connection and provider | connection.established · connection.closed · connection.error · provider.initialized · driver.validation.started · driver.validation.completed · driver.validation.failed |
| History and state | history.loaded · history.updated · state.sync.started · state.sync.completed |
| Undo | undo.started · undo.completed · undo.failed · undo.script.rolled_back |
| Clean | clean.started · clean.completed · clean.failed · clean.object.removed |
| Baseline, repair, info | baseline.started · baseline.completed · baseline.failed · repair.started · repair.completed · repair.failed · info.started · info.completed · info.failed |
| Export | export.started · export.completed · export.failed · export.object.exported · export.file.written |
| Snapshot | snapshot.started · snapshot.completed · snapshot.loaded · snapshot.saved |
| Callback lifecycle | callback.started · callback.completed · callback.failed · callback.before_migrate · callback.after_migrate · callback.after_migrate_error · callback.before_each · callback.after_each · callback.before_each_migrate · callback.after_each_migrate · callback.before_repeatable · callback.after_repeatable · callback.before_versioned · callback.after_versioned · callback.before_validate · callback.after_validate · callback.before_each_validate · callback.after_each_validate · callback.before_clean · callback.after_clean · callback.after_clean_error · callback.before_each_clean · callback.after_each_clean · callback.before_undo · callback.after_undo · callback.after_undo_error |
Isolation and error handling
Each DBLiftClient owns its own emitter and binds it for the duration of every public operation, so script-level events raised deep in the migration engine reach that client's listeners and no other's. A listener that raises is caught and logged; it never interrupts the migration.
Filename callbacks — beforeMigrate__*.sql and the rest — are a separate mechanism. See Naming Conventions.