some cleanup for metadata w/ burnettk

This commit is contained in:
jasquat 2022-11-29 16:19:55 -05:00
parent 4617974636
commit 45eafc6060
3 changed files with 50 additions and 25 deletions

View File

@ -12,7 +12,6 @@ from typing import Union
import connexion # type: ignore import connexion # type: ignore
import flask.wrappers import flask.wrappers
import jinja2 import jinja2
from spiffworkflow_backend.models.process_instance_metadata import ProcessInstanceMetadataModel
import werkzeug import werkzeug
from flask import Blueprint from flask import Blueprint
from flask import current_app from flask import current_app
@ -28,10 +27,12 @@ from lxml import etree # type: ignore
from lxml.builder import ElementMaker # type: ignore from lxml.builder import ElementMaker # type: ignore
from SpiffWorkflow.task import Task as SpiffTask # type: ignore from SpiffWorkflow.task import Task as SpiffTask # type: ignore
from SpiffWorkflow.task import TaskState from SpiffWorkflow.task import TaskState
from sqlalchemy import and_, func from sqlalchemy import and_
from sqlalchemy import asc from sqlalchemy import asc
from sqlalchemy import desc from sqlalchemy import desc
from sqlalchemy.orm import aliased, joinedload from sqlalchemy import func
from sqlalchemy.orm import aliased
from sqlalchemy.orm import joinedload
from spiffworkflow_backend.exceptions.process_entity_not_found_error import ( from spiffworkflow_backend.exceptions.process_entity_not_found_error import (
ProcessEntityNotFoundError, ProcessEntityNotFoundError,
@ -53,6 +54,9 @@ from spiffworkflow_backend.models.process_instance import ProcessInstanceApiSche
from spiffworkflow_backend.models.process_instance import ProcessInstanceModel from spiffworkflow_backend.models.process_instance import ProcessInstanceModel
from spiffworkflow_backend.models.process_instance import ProcessInstanceModelSchema from spiffworkflow_backend.models.process_instance import ProcessInstanceModelSchema
from spiffworkflow_backend.models.process_instance import ProcessInstanceStatus from spiffworkflow_backend.models.process_instance import ProcessInstanceStatus
from spiffworkflow_backend.models.process_instance_metadata import (
ProcessInstanceMetadataModel,
)
from spiffworkflow_backend.models.process_instance_report import ( from spiffworkflow_backend.models.process_instance_report import (
ProcessInstanceReportModel, ProcessInstanceReportModel,
) )
@ -814,9 +818,9 @@ def process_instance_list(
# process_model_identifier = un_modify_modified_process_model_id(modified_process_model_identifier) # process_model_identifier = un_modify_modified_process_model_id(modified_process_model_identifier)
process_instance_query = ProcessInstanceModel.query process_instance_query = ProcessInstanceModel.query
# Always join that hot user table for good performance at serialization time. # Always join that hot user table for good performance at serialization time.
# process_instance_query = process_instance_query.options( process_instance_query = process_instance_query.options(
# joinedload(ProcessInstanceModel.process_initiator, ProcessInstanceModel.process_initiator_id == UserModel.id) joinedload(ProcessInstanceModel.process_initiator)
# ) )
if report_filter.process_model_identifier is not None: if report_filter.process_model_identifier is not None:
process_model = get_process_model( process_model = get_process_model(
@ -929,14 +933,22 @@ def process_instance_list(
UserGroupAssignmentModel.user_id == g.user.id UserGroupAssignmentModel.user_id == g.user.id
) )
stock_columns = ProcessInstanceReportService.get_column_names_for_model(ProcessInstanceModel) stock_columns = ProcessInstanceReportService.get_column_names_for_model(
for column in process_instance_report.report_metadata['columns']: ProcessInstanceModel
if column['accessor'] in stock_columns: )
for column in process_instance_report.report_metadata["columns"]:
if column["accessor"] in stock_columns:
continue continue
instance_metadata_alias = aliased(ProcessInstanceMetadataModel) instance_metadata_alias = aliased(ProcessInstanceMetadataModel)
process_instance_query = ( process_instance_query = (
process_instance_query.options(joinedload(instance_metadata_alias, ProcessInstanceModel.id == instance_metadata_alias.process_instance_id, innerjoin=False)).filter(instance_metadata_alias.key == column['accessor']) process_instance_query.outerjoin(
.add_columns(func.max(instance_metadata_alias.value).label(column['accessor'])) instance_metadata_alias,
ProcessInstanceModel.id == instance_metadata_alias.process_instance_id,
)
.filter(instance_metadata_alias.key == column["accessor"])
.add_columns(
func.max(instance_metadata_alias.value).label(column["accessor"])
)
) )
process_instances = ( process_instances = (
@ -947,7 +959,9 @@ def process_instance_list(
.paginate(page=page, per_page=per_page, error_out=False) .paginate(page=page, per_page=per_page, error_out=False)
) )
results = ProcessInstanceReportService.add_metadata_columns_to_process_instance(process_instances.items, process_instance_report.report_metadata['columns']) results = ProcessInstanceReportService.add_metadata_columns_to_process_instance(
process_instances.items, process_instance_report.report_metadata["columns"]
)
report_metadata = process_instance_report.report_metadata report_metadata = process_instance_report.report_metadata
response_json = { response_json = {

View File

@ -1,9 +1,11 @@
"""Process_instance_report_service.""" """Process_instance_report_service."""
from dataclasses import dataclass from dataclasses import dataclass
from flask_bpmn.models.db import db
from typing import Optional from typing import Optional
from spiffworkflow_backend.models.process_instance import ProcessInstanceModel
import sqlalchemy
from flask_bpmn.models.db import db
from spiffworkflow_backend.models.process_instance import ProcessInstanceModel
from spiffworkflow_backend.models.process_instance_report import ( from spiffworkflow_backend.models.process_instance_report import (
ProcessInstanceReportModel, ProcessInstanceReportModel,
) )
@ -245,18 +247,26 @@ class ProcessInstanceReportService:
return report_filter return report_filter
@classmethod @classmethod
def add_metadata_columns_to_process_instance(cls, process_instance_sqlalchemy_rows, metadata_columns: list[dict]) -> list[dict]: def add_metadata_columns_to_process_instance(
cls,
process_instance_sqlalchemy_rows: list[sqlalchemy.engine.row.Row], # type: ignore
metadata_columns: list[dict],
) -> list[dict]:
"""Add_metadata_columns_to_process_instance."""
stock_columns = cls.get_column_names_for_model(ProcessInstanceModel) stock_columns = cls.get_column_names_for_model(ProcessInstanceModel)
results = [] results = []
for process_instance in process_instance_sqlalchemy_rows: for process_instance in process_instance_sqlalchemy_rows:
process_instance_dict = process_instance['ProcessInstanceModel'].serialized process_instance_dict = process_instance["ProcessInstanceModel"].serialized
for metadata_column in metadata_columns: for metadata_column in metadata_columns:
if metadata_column['accessor'] not in stock_columns: if metadata_column["accessor"] not in stock_columns:
process_instance_dict[metadata_column['accessor']] = process_instance[metadata_column['accessor']] process_instance_dict[
metadata_column["accessor"]
] = process_instance[metadata_column["accessor"]]
results.append(process_instance_dict) results.append(process_instance_dict)
return results return results
@classmethod @classmethod
def get_column_names_for_model(cls, model: db.Model) -> list[str]: def get_column_names_for_model(cls, model: db.Model) -> list[str]: # type: ignore
"""Get_column_names_for_model."""
return [i.name for i in model.__table__.columns] return [i.name for i in model.__table__.columns]

View File

@ -4,13 +4,11 @@ import json
import os import os
import time import time
from typing import Any from typing import Any
from conftest import with_super_admin_user
import pytest import pytest
from flask.app import Flask from flask.app import Flask
from flask.testing import FlaskClient from flask.testing import FlaskClient
from flask_bpmn.models.db import db from flask_bpmn.models.db import db
from spiffworkflow_backend.models.process_instance_metadata import ProcessInstanceMetadataModel
from tests.spiffworkflow_backend.helpers.base_test import BaseTest from tests.spiffworkflow_backend.helpers.base_test import BaseTest
from tests.spiffworkflow_backend.helpers.test_data import load_test_spec from tests.spiffworkflow_backend.helpers.test_data import load_test_spec
@ -22,6 +20,9 @@ from spiffworkflow_backend.models.group import GroupModel
from spiffworkflow_backend.models.process_group import ProcessGroup from spiffworkflow_backend.models.process_group import ProcessGroup
from spiffworkflow_backend.models.process_instance import ProcessInstanceModel from spiffworkflow_backend.models.process_instance import ProcessInstanceModel
from spiffworkflow_backend.models.process_instance import ProcessInstanceStatus from spiffworkflow_backend.models.process_instance import ProcessInstanceStatus
from spiffworkflow_backend.models.process_instance_metadata import (
ProcessInstanceMetadataModel,
)
from spiffworkflow_backend.models.process_instance_report import ( from spiffworkflow_backend.models.process_instance_report import (
ProcessInstanceReportModel, ProcessInstanceReportModel,
) )
@ -2554,10 +2555,11 @@ class TestProcessApi(BaseTest):
with_db_and_bpmn_file_cleanup: None, with_db_and_bpmn_file_cleanup: None,
with_super_admin_user: UserModel, with_super_admin_user: UserModel,
) -> None: ) -> None:
"""Test_can_get_process_instance_list_with_report_metadata."""
process_model = load_test_spec( process_model = load_test_spec(
process_model_id='test-process-instance-metadata-report', process_model_id="test-process-instance-metadata-report",
bpmn_file_name='process_instance_metadata.bpmn', bpmn_file_name="process_instance_metadata.bpmn",
process_model_source_directory='test-process-instance-metadata-report', process_model_source_directory="test-process-instance-metadata-report",
) )
process_instance = self.create_process_instance_from_process_model( process_instance = self.create_process_instance_from_process_model(
process_model=process_model, user=with_super_admin_user process_model=process_model, user=with_super_admin_user
@ -2570,7 +2572,6 @@ class TestProcessApi(BaseTest):
).all() ).all()
assert len(process_instance_metadata) == 2 assert len(process_instance_metadata) == 2
report_metadata = { report_metadata = {
"columns": [ "columns": [
{"Header": "ID", "accessor": "id"}, {"Header": "ID", "accessor": "id"},