store the process instance data id on the process instance and not the other way around w/ burnettk
This commit is contained in:
parent
ab50e7ac03
commit
e2891425fc
|
@ -0,0 +1,50 @@
|
||||||
|
"""empty message
|
||||||
|
|
||||||
|
Revision ID: 553ba18e4076
|
||||||
|
Revises: e494a3955ce5
|
||||||
|
Create Date: 2023-03-01 11:31:20.619328
|
||||||
|
|
||||||
|
"""
|
||||||
|
from alembic import op
|
||||||
|
import sqlalchemy as sa
|
||||||
|
from sqlalchemy.dialects import mysql
|
||||||
|
|
||||||
|
# revision identifiers, used by Alembic.
|
||||||
|
revision = '553ba18e4076'
|
||||||
|
down_revision = 'e494a3955ce5'
|
||||||
|
branch_labels = None
|
||||||
|
depends_on = None
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade():
|
||||||
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
|
op.add_column('process_instance', sa.Column('process_instance_data_id', sa.Integer(), nullable=True))
|
||||||
|
op.create_foreign_key(None, 'process_instance', 'process_instance_data', ['process_instance_data_id'], ['id'])
|
||||||
|
op.alter_column('process_instance_data', 'runtime_json',
|
||||||
|
existing_type=mysql.JSON(),
|
||||||
|
nullable=False)
|
||||||
|
op.drop_constraint('process_instance_data_ibfk_1', 'process_instance_data', type_='foreignkey')
|
||||||
|
op.drop_column('process_instance_data', 'process_instance_id')
|
||||||
|
op.alter_column('serialized_bpmn_definition', 'static_json',
|
||||||
|
existing_type=mysql.JSON(),
|
||||||
|
nullable=False)
|
||||||
|
op.drop_index('ix_serialized_bpmn_definition_hash', table_name='serialized_bpmn_definition')
|
||||||
|
op.create_index(op.f('ix_serialized_bpmn_definition_hash'), 'serialized_bpmn_definition', ['hash'], unique=True)
|
||||||
|
# ### end Alembic commands ###
|
||||||
|
|
||||||
|
|
||||||
|
def downgrade():
|
||||||
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
|
op.drop_index(op.f('ix_serialized_bpmn_definition_hash'), table_name='serialized_bpmn_definition')
|
||||||
|
op.create_index('ix_serialized_bpmn_definition_hash', 'serialized_bpmn_definition', ['hash'], unique=False)
|
||||||
|
op.alter_column('serialized_bpmn_definition', 'static_json',
|
||||||
|
existing_type=mysql.JSON(),
|
||||||
|
nullable=True)
|
||||||
|
op.add_column('process_instance_data', sa.Column('process_instance_id', mysql.INTEGER(), autoincrement=False, nullable=False))
|
||||||
|
op.create_foreign_key('process_instance_data_ibfk_1', 'process_instance_data', 'process_instance', ['process_instance_id'], ['id'])
|
||||||
|
op.alter_column('process_instance_data', 'runtime_json',
|
||||||
|
existing_type=mysql.JSON(),
|
||||||
|
nullable=True)
|
||||||
|
op.drop_constraint(None, 'process_instance', type_='foreignkey')
|
||||||
|
op.drop_column('process_instance', 'process_instance_data_id')
|
||||||
|
# ### end Alembic commands ###
|
|
@ -1,6 +1,7 @@
|
||||||
"""Process_instance."""
|
"""Process_instance."""
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
from spiffworkflow_backend.models.process_instance_data import ProcessInstanceDataModel
|
||||||
from spiffworkflow_backend.models.serialized_bpmn_definition import SerializedBpmnDefinitionModel # noqa: F401
|
from spiffworkflow_backend.models.serialized_bpmn_definition import SerializedBpmnDefinitionModel # noqa: F401
|
||||||
|
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
@ -65,7 +66,7 @@ class ProcessInstanceModel(SpiffworkflowBaseDBModel):
|
||||||
serialized_bpmn_definition_id: Optional[int] = db.Column(ForeignKey(SerializedBpmnDefinitionModel.id), nullable=True) # type: ignore
|
serialized_bpmn_definition_id: Optional[int] = db.Column(ForeignKey(SerializedBpmnDefinitionModel.id), nullable=True) # type: ignore
|
||||||
serialized_bpmn_definition = relationship("SerializedBpmnDefinitionModel")
|
serialized_bpmn_definition = relationship("SerializedBpmnDefinitionModel")
|
||||||
|
|
||||||
# added mostly for the cascade delete
|
process_instance_data_id: Optional[int] = db.Column(ForeignKey(ProcessInstanceDataModel.id), nullable=True) # type: ignore
|
||||||
process_instance_data = relationship("ProcessInstanceDataModel", cascade="delete") # type: ignore
|
process_instance_data = relationship("ProcessInstanceDataModel", cascade="delete") # type: ignore
|
||||||
|
|
||||||
active_human_tasks = relationship(
|
active_human_tasks = relationship(
|
||||||
|
|
|
@ -1,9 +1,6 @@
|
||||||
"""Process_instance."""
|
"""Process_instance."""
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
from sqlalchemy import ForeignKey
|
|
||||||
from spiffworkflow_backend.models.process_instance import ProcessInstanceModel
|
|
||||||
|
|
||||||
from sqlalchemy.orm import deferred
|
|
||||||
|
|
||||||
from spiffworkflow_backend.models.db import db
|
from spiffworkflow_backend.models.db import db
|
||||||
from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel
|
from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel
|
||||||
|
@ -23,7 +20,5 @@ class ProcessInstanceDataModel(SpiffworkflowBaseDBModel):
|
||||||
|
|
||||||
__tablename__ = "process_instance_data"
|
__tablename__ = "process_instance_data"
|
||||||
id: int = db.Column(db.Integer, primary_key=True)
|
id: int = db.Column(db.Integer, primary_key=True)
|
||||||
process_instance_id: int = db.Column(
|
# this is not deferred because there is no reason to query this model if you do not want the runtime_json
|
||||||
ForeignKey(ProcessInstanceModel.id), nullable=False # type: ignore
|
runtime_json: str = db.Column(db.JSON, nullable=False)
|
||||||
)
|
|
||||||
runtime_json: str | None = deferred(db.Column(db.JSON)) # type: ignore
|
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
"""Process_instance."""
|
"""Process_instance."""
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from sqlalchemy.orm import deferred
|
|
||||||
|
|
||||||
from spiffworkflow_backend.models.db import db
|
from spiffworkflow_backend.models.db import db
|
||||||
from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel
|
from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel
|
||||||
|
|
||||||
|
@ -46,5 +44,5 @@ class SerializedBpmnDefinitionModel(SpiffworkflowBaseDBModel):
|
||||||
|
|
||||||
__tablename__ = "serialized_bpmn_definition"
|
__tablename__ = "serialized_bpmn_definition"
|
||||||
id: int = db.Column(db.Integer, primary_key=True)
|
id: int = db.Column(db.Integer, primary_key=True)
|
||||||
hash: str = db.Column(db.String(255), nullable=False, index=True)
|
hash: str = db.Column(db.String(255), nullable=False, index=True, unique=True)
|
||||||
static_json: str | None = deferred(db.Column(db.JSON)) # type: ignore
|
static_json: str = db.Column(db.JSON, nullable=False)
|
||||||
|
|
|
@ -25,7 +25,6 @@ from spiffworkflow_backend.models.process_instance import ProcessInstanceModelSc
|
||||||
from spiffworkflow_backend.models.process_instance import (
|
from spiffworkflow_backend.models.process_instance import (
|
||||||
ProcessInstanceTaskDataCannotBeUpdatedError,
|
ProcessInstanceTaskDataCannotBeUpdatedError,
|
||||||
)
|
)
|
||||||
from spiffworkflow_backend.models.process_instance_data import ProcessInstanceDataModel
|
|
||||||
from spiffworkflow_backend.models.process_model import ProcessModelInfo
|
from spiffworkflow_backend.models.process_model import ProcessModelInfo
|
||||||
from spiffworkflow_backend.models.spec_reference import SpecReferenceCache
|
from spiffworkflow_backend.models.spec_reference import SpecReferenceCache
|
||||||
from spiffworkflow_backend.models.spec_reference import SpecReferenceSchema
|
from spiffworkflow_backend.models.spec_reference import SpecReferenceSchema
|
||||||
|
@ -191,11 +190,11 @@ def task_data_update(
|
||||||
if process_instance:
|
if process_instance:
|
||||||
if process_instance.status != "suspended":
|
if process_instance.status != "suspended":
|
||||||
raise ProcessInstanceTaskDataCannotBeUpdatedError(
|
raise ProcessInstanceTaskDataCannotBeUpdatedError(
|
||||||
"The process instance needs to be suspended to udpate the task-data."
|
"The process instance needs to be suspended to update the task-data."
|
||||||
f" It is currently: {process_instance.status}"
|
f" It is currently: {process_instance.status}"
|
||||||
)
|
)
|
||||||
|
|
||||||
process_instance_data = ProcessInstanceDataModel.query.filter_by(process_instance_id=process_instance.id).first()
|
process_instance_data = process_instance.process_instance_data
|
||||||
if process_instance_data is None:
|
if process_instance_data is None:
|
||||||
raise ApiError(
|
raise ApiError(
|
||||||
error_code="process_instance_data_not_found",
|
error_code="process_instance_data_not_found",
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
"""APIs for dealing with process groups, process models, and process instances."""
|
"""APIs for dealing with process groups, process models, and process instances."""
|
||||||
import json
|
import json
|
||||||
from spiffworkflow_backend.models.process_instance_data import ProcessInstanceDataModel
|
|
||||||
from typing import Any
|
from typing import Any
|
||||||
from typing import Dict
|
from typing import Dict
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
@ -552,7 +551,7 @@ def process_instance_task_list(
|
||||||
|
|
||||||
step_details = step_detail_query.all()
|
step_details = step_detail_query.all()
|
||||||
|
|
||||||
process_instance_data = ProcessInstanceDataModel.query.filter_by(process_instance_id=process_instance.id).first()
|
process_instance_data = process_instance.process_instance_data
|
||||||
process_instance_data_json = "{}" if process_instance_data is None else process_instance_data.runtime_json
|
process_instance_data_json = "{}" if process_instance_data is None else process_instance_data.runtime_json
|
||||||
process_instance_data_dict = json.loads(process_instance_data_json)
|
process_instance_data_dict = json.loads(process_instance_data_json)
|
||||||
tasks = process_instance_data_dict["tasks"]
|
tasks = process_instance_data_dict["tasks"]
|
||||||
|
|
|
@ -524,7 +524,7 @@ class ProcessInstanceProcessor:
|
||||||
if process_instance_model.serialized_bpmn_definition_id is None:
|
if process_instance_model.serialized_bpmn_definition_id is None:
|
||||||
return {}
|
return {}
|
||||||
serialized_bpmn_definition = process_instance_model.serialized_bpmn_definition
|
serialized_bpmn_definition = process_instance_model.serialized_bpmn_definition
|
||||||
process_instance_data = ProcessInstanceDataModel.query.filter_by(process_instance_id=process_instance_model.id).first()
|
process_instance_data = process_instance_model.process_instance_data
|
||||||
loaded_json: dict = json.loads(serialized_bpmn_definition.static_json or '{}')
|
loaded_json: dict = json.loads(serialized_bpmn_definition.static_json or '{}')
|
||||||
loaded_json.update(json.loads(process_instance_data.runtime_json))
|
loaded_json.update(json.loads(process_instance_data.runtime_json))
|
||||||
return loaded_json
|
return loaded_json
|
||||||
|
@ -847,7 +847,11 @@ class ProcessInstanceProcessor:
|
||||||
)
|
)
|
||||||
return subprocesses_by_child_task_ids
|
return subprocesses_by_child_task_ids
|
||||||
|
|
||||||
def add_bpmn_json_records(self) -> None:
|
def _add_bpmn_json_records(self) -> None:
|
||||||
|
"""Adds serialized_bpmn_definition and process_instance_data records to the db session.
|
||||||
|
|
||||||
|
Expects the save method to commit it.
|
||||||
|
"""
|
||||||
bpmn_dict = json.loads(self.serialize())
|
bpmn_dict = json.loads(self.serialize())
|
||||||
bpmn_dict_keys = ('spec', 'subprocess_specs', 'serializer_version')
|
bpmn_dict_keys = ('spec', 'subprocess_specs', 'serializer_version')
|
||||||
bpmn_spec_dict = {}
|
bpmn_spec_dict = {}
|
||||||
|
@ -866,16 +870,19 @@ class ProcessInstanceProcessor:
|
||||||
db.session.add(serialized_bpmn_definition)
|
db.session.add(serialized_bpmn_definition)
|
||||||
self.process_instance_model.serialized_bpmn_definition = serialized_bpmn_definition
|
self.process_instance_model.serialized_bpmn_definition = serialized_bpmn_definition
|
||||||
|
|
||||||
process_instance_data = ProcessInstanceDataModel.query.filter_by(process_instance_id=self.process_instance_model.id).first()
|
process_instance_data = None
|
||||||
if process_instance_data is None:
|
if self.process_instance_model.process_instance_data_id is None:
|
||||||
process_instance_data = ProcessInstanceDataModel(process_instance_id=self.process_instance_model.id)
|
process_instance_data = ProcessInstanceDataModel()
|
||||||
|
else:
|
||||||
|
process_instance_data = self.process_instance_model.process_instance_data
|
||||||
|
|
||||||
process_instance_data.runtime_json = json.dumps(process_instance_data_dict)
|
process_instance_data.runtime_json = json.dumps(process_instance_data_dict)
|
||||||
db.session.add(process_instance_data)
|
db.session.add(process_instance_data)
|
||||||
|
self.process_instance_model.process_instance_data = process_instance_data
|
||||||
|
|
||||||
def save(self) -> None:
|
def save(self) -> None:
|
||||||
"""Saves the current state of this processor to the database."""
|
"""Saves the current state of this processor to the database."""
|
||||||
self.add_bpmn_json_records()
|
self._add_bpmn_json_records()
|
||||||
|
|
||||||
complete_states = [TaskState.CANCELLED, TaskState.COMPLETED]
|
complete_states = [TaskState.CANCELLED, TaskState.COMPLETED]
|
||||||
user_tasks = list(self.get_all_user_tasks())
|
user_tasks = list(self.get_all_user_tasks())
|
||||||
|
|
Loading…
Reference in New Issue