From 2acd6d319c6bebd0a219f68ca3855b0d8cb974f0 Mon Sep 17 00:00:00 2001 From: sbilge Date: Thu, 15 Aug 2024 13:35:55 +0000 Subject: [PATCH] model transformation fn added --- .../count_references/assumptions.py | 14 ++++--- .../count_references/model_transform.py | 42 +++++++++++++++++-- .../infer_relations/data_transform.py | 7 ++-- .../infer_relations/model_transform.py | 4 +- .../multiple/transformed.schemapack.yaml | 2 +- 5 files changed, 55 insertions(+), 14 deletions(-) diff --git a/src/metldata/builtin_transformations/count_references/assumptions.py b/src/metldata/builtin_transformations/count_references/assumptions.py index 88de597..903c742 100644 --- a/src/metldata/builtin_transformations/count_references/assumptions.py +++ b/src/metldata/builtin_transformations/count_references/assumptions.py @@ -38,7 +38,8 @@ def assert_class_is_source( """Make sure that the source class is the one being modified with the count property""" if instruction.class_name != instruction.source_relation_path.source: raise ModelAssumptionError( - f"Class {instruction.class_name} does not correspond to the relation source {instruction.source_relation_path.source}." + f"Class {instruction.class_name} does not correspond to the relation source { + instruction.source_relation_path.source}." ) @@ -74,13 +75,14 @@ def assert_summary_exists( schema: SchemaPack, instruction: AddReferenceCountPropertyInstruction, ) -> None: - """TODO.""" + """Make sure that the source class (the class being modified) and the object_path exists in the model.""" class_name = instruction.class_name class_def = schema.classes.get(class_name) # Check if the class exists in the model if not class_def: - raise ModelAssumptionError(f"Class {class_name} does not exist in the model.") + raise ModelAssumptionError( + f"Class {class_name} does not exist in the model.") # Check if the object_path already exists in the model try: @@ -90,12 +92,14 @@ def assert_summary_exists( ) except KeyError as err: raise ModelAssumptionError( - f"Object path {instruction.target_content.object_path} does not exist" + f"Object path { + instruction.target_content.object_path} does not exist" + f" in class {class_name}." ) from err if instruction.target_content.property_name in target_schema.get("properties", {}): raise ModelAssumptionError( - f"Property {instruction.target_content.property_name} already exists" + f"Property { + instruction.target_content.property_name} already exists" + f" in class {class_name}." ) diff --git a/src/metldata/builtin_transformations/count_references/model_transform.py b/src/metldata/builtin_transformations/count_references/model_transform.py index e0db6be..44064e3 100644 --- a/src/metldata/builtin_transformations/count_references/model_transform.py +++ b/src/metldata/builtin_transformations/count_references/model_transform.py @@ -14,18 +14,29 @@ # limitations under the License. """Model transformation logic for the 'count references' transformation""" +from copy import deepcopy + from schemapack.spec.schemapack import ( - # ClassDefinition, + ClassDefinition, SchemaPack, ) +from metldata.builtin_transformations.add_content_properties.path import ( + resolve_schema_object_path, +) +from metldata.builtin_transformations.count_references.instruction import ( + AddReferenceCountPropertyInstruction, +) +from metldata.transform.base import EvitableTransformationError + # from metldata.transform.base import EvitableTransformationError def add_count_references( - *, model: SchemaPack, instructions_by_class: dict[str, list[str]] + *, model: SchemaPack, instructions_by_class: dict[str, list[AddReferenceCountPropertyInstruction]] ) -> SchemaPack: - """Delete content properties from a model. + """Add a new content property (target_content) to the class(es) subject to + transformation Args: model: @@ -34,5 +45,30 @@ def add_count_references( The model with the """ # TODO model transform logic for count references + updated_class_defs: dict[str, ClassDefinition] = {} + for class_name, cls_instructions in instructions_by_class.items(): + for class_name, cls_instructions in instructions_by_class.items(): + class_def = model.classes.get(class_name) + + if not class_def: + raise EvitableTransformationError() + + content_schema = class_def.content.json_schema_dict + + for cls_instruction in cls_instructions: + try: + target_object = resolve_schema_object_path( + content_schema, cls_instruction.target_content.object_path + ) + except KeyError as e: + raise EvitableTransformationError() from e + + if cls_instruction.target_content.property_name in content_schema.get( + "properties", {} + ): + raise EvitableTransformationError() + target_object.setdefault("properties", {})[ + cls_instruction.target_content.property_name + ] = deepcopy(cls_instruction.content_schema) return model diff --git a/src/metldata/builtin_transformations/infer_relations/data_transform.py b/src/metldata/builtin_transformations/infer_relations/data_transform.py index f941d24..64e307f 100644 --- a/src/metldata/builtin_transformations/infer_relations/data_transform.py +++ b/src/metldata/builtin_transformations/infer_relations/data_transform.py @@ -47,10 +47,10 @@ from schemapack.spec.custom_types import ResourceId from schemapack.spec.datapack import DataPack, Resource -from metldata.builtin_transformations.infer_relations.path.path import ( +from metldata.builtin_transformations.common.path.path import ( RelationPath, ) -from metldata.builtin_transformations.infer_relations.path.path_elements import ( +from metldata.builtin_transformations.common.path.path_elements import ( RelationPathElement, RelationPathElementType, ) @@ -133,7 +133,8 @@ def resolve_passive_path_element( target_resource_ids = set() for candidate_resource_id, candidate_resource in candidate_resources.items(): - relation = candidate_resource.relations.get(path_element.property, set()) + relation = candidate_resource.relations.get( + path_element.property, set()) if ( isinstance(relation, set) and source_resource_id in relation diff --git a/src/metldata/builtin_transformations/infer_relations/model_transform.py b/src/metldata/builtin_transformations/infer_relations/model_transform.py index 41c9efa..502fe35 100644 --- a/src/metldata/builtin_transformations/infer_relations/model_transform.py +++ b/src/metldata/builtin_transformations/infer_relations/model_transform.py @@ -24,8 +24,8 @@ SchemaPack, ) -from metldata.builtin_transformations.infer_relations.path.path import RelationPath -from metldata.builtin_transformations.infer_relations.path.path_elements import ( +from metldata.builtin_transformations.common.path.path import RelationPath +from metldata.builtin_transformations.common.path.path_elements import ( RelationPathElement, RelationPathElementType, ) diff --git a/tests/fixtures/example_transformations/count_references/multiple/transformed.schemapack.yaml b/tests/fixtures/example_transformations/count_references/multiple/transformed.schemapack.yaml index 9aa8c86..5da8d14 100644 --- a/tests/fixtures/example_transformations/count_references/multiple/transformed.schemapack.yaml +++ b/tests/fixtures/example_transformations/count_references/multiple/transformed.schemapack.yaml @@ -4,7 +4,7 @@ classes: File: id: propertyName: alias - content: ../example_content_schemas/File.schema.json + content: ../../../example_content_schemas/File.schema.json Dataset: id: propertyName: alias