Skip to content

commands.makeworkflowmigrations ​

Overview ​

Management command for generating workflow state and transition migrations from change history.

Classes ​

apply_and_save_changes ​

Set each changed field in data on obj, then save obj.

A changed field holds an (old, new) tuple, and reversing applies the old value. Fields that are not tuples are skipped. Generated workflow migrations copy this function.

Signature ​

apply_and_save_changes(obj, data, reversing)

Parameters ​

NameTypeRequiredDefaultDescription
objyes
datayes
reversingnoFalse

Source ​

server/vueda/workflow/management/commands/makeworkflowmigrations.py:1191

backwards_migrate_workflow ​

Undo a generated workflow migration's changed_items in reverse order.

Adds become deletes, deletes become adds, and changed fields get their old values back. Object states change only for the workflows changed_items names: a removed workflow's object states are deleted, an object in a removed state is restored from its history or reset to the initial state, and a re-created workflow gives its objects the initial state. Every other object state keeps its row and its state. Generated workflow migrations call this from their reverse step; the migrations import it when made with --import-instead and copy it otherwise.

Signature ​

backwards_migrate_workflow(apps, changed_items, change_reason)

Parameters ​

NameTypeRequiredDefaultDescription
appsyes
changed_itemsyes
change_reasonyes

Source ​

server/vueda/workflow/management/commands/makeworkflowmigrations.py:227

compare_records ​

Return the fields whose value differs between two events.

Signature ​

compare_records(old_record, new_record)

Parameters ​

NameTypeRequiredDefaultDescription
old_recordyes
new_recordyes

Source ​

server/vueda/workflow/management/commands/makeworkflowmigrations.py:1162

delete_object_states_of_removed_workflows ​

Delete the object states of each workflow the reversal of changed_items removes.

A workflow the migration added has no state left to give its objects once the reversal removes it, and its object states protect it from deletion. Returns the record of released object states that release_state_objects and settle_released_object_states add to. Generated workflow migrations copy this function and reach it through backwards_migrate_workflow.

Signature ​

delete_object_states_of_removed_workflows(apps, changed_items)

Parameters ​

NameTypeRequiredDefaultDescription
appsyes
changed_itemsyes

Source ​

server/vueda/workflow/management/commands/makeworkflowmigrations.py:890

forwards_migrate_workflow ​

Apply a generated workflow migration's changed_items in order, then sync workflow object states.

Generated workflow migrations call this from their forwards step; the migrations import it when made with --import-instead and copy it otherwise. All writes are grouped under one migration action named by change_reason.

Signature ​

forwards_migrate_workflow(apps, changed_items, change_reason)

Parameters ​

NameTypeRequiredDefaultDescription
appsyes
changed_itemsyes
change_reasonyes

Source ​

server/vueda/workflow/management/commands/makeworkflowmigrations.py:180

get_attr_names_for_workflow_models ​

Map each workflow model name to a mapping of its field names to their attribute names (attname).

The command adds fields renamed by migrations to this, then reads recorded field names through it.

Signature ​

get_attr_names_for_workflow_models()

Source ​

server/vueda/workflow/management/commands/makeworkflowmigrations.py:1096

get_history_diff ​

Classify one write and return what it changed.

A write with nothing before it is an add, and one whose event records a delete is a delete. Each compares against an empty row of the same model, so every field the write set or cleared shows up as a change.

Signature ​

get_history_diff(old_history_record, new_history_record)

Parameters ​

NameTypeRequiredDefaultDescription
old_history_recordyes
new_history_recordyes

Source ​

server/vueda/workflow/management/commands/makeworkflowmigrations.py:1172

get_id_values_from_dict ​

Return id_data with each value passed through get_id_values_from_item.

The result finds the row as it stands now. Generated workflow migrations copy this function.

Signature ​

get_id_values_from_dict(id_data, reversing)

Parameters ​

NameTypeRequiredDefaultDescription
id_datayes
reversingnoFalse

Source ​

server/vueda/workflow/management/commands/makeworkflowmigrations.py:1065

get_id_values_from_item ​

Return the value that finds a row as it stands now: the old side of an (old, new) tuple.

reversing picks the new side instead. A value that is not a tuple is returned unchanged. Generated workflow migrations copy this function.

Signature ​

get_id_values_from_item(values, reversing)

Parameters ​

NameTypeRequiredDefaultDescription
valuesyes
reversingnoFalse

Source ​

server/vueda/workflow/management/commands/makeworkflowmigrations.py:1050

get_migration_imports ​

Return the full, ordered set of import lines a workflow migration file's import section is replaced with.

direct_runpython_import adds a direct from django.db.migrations import RunPython import, needed when the class Migration block being preserved calls RunPython(...) directly instead of migrations.RunPython(...).

When as_mapping is True, an ordered mapping is returned instead: keys are single-name tuples (an import only ever binds one name, per this project's force-single-line isort convention) and values are the current import line, each ending in its own newline and prefixed with a blank line where it opens a new isort group. This is used by updateworkflowmigrations to update or insert only the imports it recognizes in an existing migration, leaving any hand-added imports (or comments) around them untouched.

Signature ​

get_migration_imports(import_instead, direct_runpython_import, as_mapping)

Parameters ​

NameTypeRequiredDefaultDescription
import_insteadnoFalse
direct_runpython_importnoFalse
as_mappingnoFalse

Source ​

server/vueda/workflow/management/commands/makeworkflowmigrations.py:1215

get_migration_sources ​

Return the source-code strings that follow changed_data in a workflow migration file.

When as_mapping is True, an ordered mapping is returned instead: keys are tuples of every name (old and current) that identifies a given function/class across versions of this command, and values are the current source for it. This is used by updateworkflowmigrations to replace only the functions it recognizes in an existing migration, leaving any hand-added code around them untouched.

Signature ​

get_migration_sources(import_instead, as_mapping)

Parameters ​

NameTypeRequiredDefaultDescription
import_insteadnoFalse
as_mappingnoFalse

Source ​

server/vueda/workflow/management/commands/makeworkflowmigrations.py:1277

handle_initial_state ​

Add, change, or delete a workflow's initial state to match changed_item.

The function finds related rows by the identifying fields stored in changed_item. reversing restores old values on a change. Generated workflow migrations copy this function and reach it through forwards_migrate_workflow and backwards_migrate_workflow.

Signature ​

handle_initial_state(apps, changed_item, change_reason, reversing)

Parameters ​

NameTypeRequiredDefaultDescription
appsyes
changed_itemyes
change_reasonyes
reversingnoFalse

Source ​

server/vueda/workflow/management/commands/makeworkflowmigrations.py:534

handle_state ​

Add, change, or delete one workflow state to match changed_item.

The function finds related rows by the identifying fields stored in changed_item. reversing restores old values on a change. Generated workflow migrations copy this function and reach it through forwards_migrate_workflow and backwards_migrate_workflow.

Signature ​

handle_state(apps, changed_item, change_reason, reversing)

Parameters ​

NameTypeRequiredDefaultDescription
appsyes
changed_itemyes
change_reasonyes
reversingnoFalse

Source ​

server/vueda/workflow/management/commands/makeworkflowmigrations.py:414

handle_state_objects ​

Run manage_state_objects for every workflow, using the migration's own models.

reversing deletes all object states instead. Generated workflow migrations copy this function and reach it through forwards_migrate_workflow and backwards_migrate_workflow.

Signature ​

handle_state_objects(apps, reversing)

Parameters ​

NameTypeRequiredDefaultDescription
appsyes
reversingnoFalse

Source ​

server/vueda/workflow/management/commands/makeworkflowmigrations.py:860

handle_state_permission ​

Add, change, or delete one state permission (a group's permission in a state) to match changed_item.

The function finds related rows by the identifying fields stored in changed_item. reversing restores old values on a change. Generated workflow migrations copy this function and reach it through forwards_migrate_workflow and backwards_migrate_workflow.

Signature ​

handle_state_permission(apps, changed_item, change_reason, reversing)

Parameters ​

NameTypeRequiredDefaultDescription
appsyes
changed_itemyes
change_reasonyes
reversingnoFalse

Source ​

server/vueda/workflow/management/commands/makeworkflowmigrations.py:453

handle_transition ​

Add, change, or delete one transition to match changed_item.

The function finds related rows by the identifying fields stored in changed_item. reversing restores old values on a change. Generated workflow migrations copy this function and reach it through forwards_migrate_workflow and backwards_migrate_workflow.

Signature ​

handle_transition(apps, changed_item, change_reason, reversing)

Parameters ​

NameTypeRequiredDefaultDescription
appsyes
changed_itemyes
change_reasonyes
reversingnoFalse

Source ​

server/vueda/workflow/management/commands/makeworkflowmigrations.py:597

handle_transition_permission ​

Add, change, or delete one transition permission to match changed_item.

The function finds related rows by the identifying fields stored in changed_item. reversing restores old values on a change. Generated workflow migrations copy this function and reach it through forwards_migrate_workflow and backwards_migrate_workflow.

Signature ​

handle_transition_permission(apps, changed_item, change_reason, reversing)

Parameters ​

NameTypeRequiredDefaultDescription
appsyes
changed_itemyes
change_reasonyes
reversingnoFalse

Source ​

server/vueda/workflow/management/commands/makeworkflowmigrations.py:653

handle_transition_source ​

Add, change, or delete one transition source state to match changed_item.

The function finds related rows by the identifying fields stored in changed_item. reversing restores old values on a change. Generated workflow migrations copy this function and reach it through forwards_migrate_workflow and backwards_migrate_workflow.

Signature ​

handle_transition_source(apps, changed_item, change_reason, reversing)

Parameters ​

NameTypeRequiredDefaultDescription
appsyes
changed_itemyes
change_reasonyes
reversingnoFalse

Source ​

server/vueda/workflow/management/commands/makeworkflowmigrations.py:732

handle_workflow ​

Add, change, or delete one workflow to match changed_item.

The function finds related rows by the identifying fields stored in changed_item. reversing restores old values on a change. Generated workflow migrations copy this function and reach it through forwards_migrate_workflow and backwards_migrate_workflow.

Signature ​

handle_workflow(apps, changed_item, change_reason, reversing)

Parameters ​

NameTypeRequiredDefaultDescription
appsyes
changed_itemyes
change_reasonyes
reversingnoFalse

Source ​

server/vueda/workflow/management/commands/makeworkflowmigrations.py:320

handle_workflow_permission ​

Add, change, or delete one workflow permission to match changed_item.

The function finds related rows by the identifying fields stored in changed_item. reversing restores old values on a change. Generated workflow migrations copy this function and reach it through forwards_migrate_workflow and backwards_migrate_workflow.

Signature ​

handle_workflow_permission(apps, changed_item, change_reason, reversing)

Parameters ​

NameTypeRequiredDefaultDescription
appsyes
changed_itemyes
change_reasonyes
reversingnoFalse

Source ​

server/vueda/workflow/management/commands/makeworkflowmigrations.py:354

make_sure_permissions_exist ​

Create any missing permissions for the app named app_label.

Generated workflow migrations run this before applying their changes, so the permissions those changes name exist. The migrations import it when made with --import-instead and copy it otherwise.

Signature ​

make_sure_permissions_exist(app_label)

Parameters ​

NameTypeRequiredDefaultDescription
app_labelyes

Source ​

server/vueda/workflow/management/commands/makeworkflowmigrations.py:1077

manage_state_objects ​

Create missing object states and move states with only a recorded creation to the initial state.

An object state with only its creation recorded against it is still wherever it was put, so a changed initial state moves it. One that carries any later event was moved by someone, and the state they moved it to is theirs to keep. A state with no events also stays where it is: it may predate the event triggers, so missing history does not prove that it has never moved.

TODO: An earlier run of this counts as someone, because its update is an event like any other. A workflow whose initial state changes twice therefore moves its objects only the first time. Telling the two apart needs the sync's own writes to be identifiable, which the action context cannot currently do here: pghistory sets its context as a transaction-local, so an action opened around these writes is still attributed to everything else written in the same transaction.

Signature ​

manage_state_objects(workflow, obj_class, workflow_obj_state_class, object_state_event_class, reversing)

Parameters ​

NameTypeRequiredDefaultDescription
workflowyes
obj_classyes
workflow_obj_state_classyes
object_state_event_classyes
reversingnoFalse

Source ​

server/vueda/workflow/management/commands/makeworkflowmigrations.py:816

rebuild_migration_apps ​

Return a fresh registry of the models in apps, in which every relation points at a model of its own.

Some migration operations, such as AlterModelOptions and pgtrigger's AddTrigger, reload a model with delay=True. That re-renders the model and its direct relations but not the models that point at them, so a foreign key can keep an older class than apps.get_model() returns, and filtering through it raises ValueError. Django re-renders the registry before a forwards RunPython but not before a backwards one (https://code.djangoproject.com/ticket/33586), so the reverse step rebuilds it. Generated workflow migrations copy this function and reach it through backwards_migrate_workflow.

VUEDA keeps it until the oldest Django version it supports includes the fix. A copy in a migration can stay after that, because rebuilding a registry that is already consistent changes nothing.

Signature ​

rebuild_migration_apps(apps)

Parameters ​

NameTypeRequiredDefaultDescription
appsyes

Source ​

server/vueda/workflow/management/commands/makeworkflowmigrations.py:242

release_state_objects ​

Move every object out of the state that changed_item is about to delete.

Each object returns to the most recent state in its history that its workflow still has. An object with no such state moves to the workflow's initial state, or loses its object state when the workflow has none. Rows are updated in place, so each keeps its id and its history. released records each move for settle_released_object_states. Generated workflow migrations copy this function and reach it through backwards_migrate_workflow.

Signature ​

release_state_objects(apps, changed_item, released)

Parameters ​

NameTypeRequiredDefaultDescription
appsyes
changed_itemyes
releasedyes

Source ​

server/vueda/workflow/management/commands/makeworkflowmigrations.py:924

settle_released_object_states ​

Finish the object state changes of a reversal, then report them.

An object reset to the initial state moves to the initial state the workflow has once the whole reversal has run, which a later step may have changed. An object left without a state, and every object of a re-created workflow, gets that initial state. Generated workflow migrations copy this function and reach it through backwards_migrate_workflow.

Signature ​

settle_released_object_states(apps, released, recreated_workflow_ids)

Parameters ​

NameTypeRequiredDefaultDescription
appsyes
releasedyes
recreated_workflow_idsyes

Source ​

server/vueda/workflow/management/commands/makeworkflowmigrations.py:978

tracked_field_names ​

Return an event model's tracked columns as (name, attname) pairs.

pghistory copies the tracked row's concrete fields and adds its own pgh_ columns. Change data is keyed by field name and read by attname, so both are needed.

Signature ​

tracked_field_names(event_model)

Parameters ​

NameTypeRequiredDefaultDescription
event_modelyes

Source ​

server/vueda/workflow/management/commands/makeworkflowmigrations.py:1149

workflow_identity ​

Name a workflow the way a change does: its code, and the app and model it was written for.

A workflow code is unique among live workflows but not over time, so a code alone cannot say which workflow a change means once another model has taken that code over. These two columns are recorded on the workflow itself for exactly this, and they survive the content type going away.

Signature ​

workflow_identity(workflow_event)

Parameters ​

NameTypeRequiredDefaultDescription
workflow_eventyes

Source ​

server/vueda/workflow/management/commands/makeworkflowmigrations.py:1036

workflow_migration_action ​

Group every write a generated workflow migration makes under one action.

The events a migration writes are attributed to the system user and labelled with the migration that wrote them, so reading history back separates a migration's writes from a person's edit. Nothing else in the migration needs to know about it: the triggers record whatever the block writes, under whatever context is open.

The user model is read through the migration's own registry, because a migration must not depend on the shape the live model has now.

Signature ​

workflow_migration_action(apps, change_reason)

Parameters ​

NameTypeRequiredDefaultDescription
appsyes
change_reasonyes

Source ​

server/vueda/workflow/management/commands/makeworkflowmigrations.py:162

Source ​

server/vueda/workflow/management/commands/makeworkflowmigrations.py