Skip to content

Commit

Permalink
passive path support is added
Browse files Browse the repository at this point in the history
  • Loading branch information
sbilge committed Aug 27, 2024
1 parent 55522cd commit 51d2e1e
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 43 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,50 @@
from metldata.transform.base import ModelAssumptionError, MultiplicityError


def assert_class_is_source(instruction: AddReferenceCountPropertyInstruction):
"""Make sure that the source class is the one being modified with the count property"""
if instruction.class_name != instruction.source_relation_path.source:
def validate_modification_class(path_element, expected_class_name):
"""Check whether the class specified to be modified with the reference count
matches the source or target class in the provided `path_element`, depending on the
type of the relation path (i.e., active or passive). If the class does not match,
an exception is raised.
"""
modification_class_name = (
path_element.source
if path_element.type_ == RelationPathElementType.ACTIVE
else path_element.target
)
if expected_class_name != modification_class_name:
raise ModelAssumptionError(
f"Class {
expected_class_name} does not correspond to the relation source "
f"{modification_class_name}."
)


def check_class_exists(model: SchemaPack, class_name: str) -> None:
"""Check if a class exists in the model and raise an error if not"""
if class_name not in model.classes:
raise ModelAssumptionError(f"Class {class_name} not found in model.")


def check_relation_exists(model: SchemaPack, class_name: str, relation: str):
"""Check if a relation exists in a class and raise an error if not"""
if relation not in model.classes[class_name].relations:
raise ModelAssumptionError(
f"Class {instruction.class_name} does not correspond to the relation source {
instruction.source_relation_path.source}."
f"Relation property {
relation} not found in class {class_name}."
)


def assert_class_is_source(instruction: AddReferenceCountPropertyInstruction):
"""Ensure that the class being modified with the reference count property is the expected class.
This function iterates over the elements of the relation path in the given instruction
and validates that the class being modified with the reference count property matches
the class specified in the relation path.
"""
for path_element in instruction.source_relation_path.elements:
validate_modification_class(path_element, instruction.class_name)


def assert_path_classes_and_relations_exist(model: SchemaPack, path: RelationPath):
"""Make sure that all classes and relations defined in the provided path exist in
the provided model.
Expand All @@ -48,27 +83,18 @@ def assert_path_classes_and_relations_exist(model: SchemaPack, path: RelationPat
if the model does not fulfill the assumptions.
"""
for path_element in path.elements:
if path_element.source not in model.classes:
raise ModelAssumptionError(
f"Class {path_element.source} not found in model."
)
check_class_exists(model, path_element.source)
check_class_exists(model, path_element.target)

if path_element.target not in model.classes:
raise ModelAssumptionError(
f"Class {path_element.target} not found in model."
)
if path_element.type_ == RelationPathElementType.ACTIVE:
check_relation_exists(model, path_element.source, path_element.property)

if path_element.type_ == RelationPathElementType.ACTIVE and (
path_element.property not in model.classes[path_element.source].relations
):
raise ModelAssumptionError(
f"Relation property {path_element.property} not found in class"
f" {path_element.source}."
)
if path_element.type_ == RelationPathElementType.PASSIVE:
check_relation_exists(model, path_element.target, path_element.property)


def assert_multiplicity(model: SchemaPack, path: RelationPath):
"""Make sure the target of the relation conributes multiple instances to the relation."""
"""Make sure the target of the relation contributes multiple instances to the relation."""
for path_element in path.elements:
if path_element.type_ == RelationPathElementType.ACTIVE:
relation = model.classes[path_element.source].relations[
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,6 @@

from schemapack.spec.datapack import DataPack

from metldata.builtin_transformations.common.path.path_elements import (
RelationPathElementType,
)
from metldata.builtin_transformations.count_references.instruction import (
AddReferenceCountPropertyInstruction,
)
Expand Down Expand Up @@ -52,13 +49,12 @@ def count_references(

for instruction in instructions:
for path_element in instruction.source_relation_path.elements:
if path_element.type_ == RelationPathElementType.ACTIVE:
relation_slot = path_element.property
else:
raise EvitableTransformationError()
relation_slot = path_element.property

for resource in resources.values():
related_to = resource.relations.get(relation_slot)
if not related_to:
raise EvitableTransformationError()

count = len(related_to) if related_to else 0

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,18 @@
# limitations under the License.

count_references:
- class_name: Dataset
target_content:
object_path: "file_summary"
property_name: "count"
source_relation_path: "Dataset(files)>File"
- class_name: Sample
target_content:
object_path: "file_summary"
property_name: "count"
source_relation_path: "Sample(files)>File"
- class_name: Experiment
target_content:
object_path: "sample_summary"
property_name: "count"
source_relation_path: "Experiment(samples)>Sample"
- class_name: Dataset
target_content:
object_path: "file_summary"
property_name: "count"
source_relation_path: "Dataset(files)>File"
- class_name: Sample
target_content:
object_path: "file_summary"
property_name: "count"
source_relation_path: "File<(files)Sample"
- class_name: Experiment
target_content:
object_path: "sample_summary"
property_name: "count"
source_relation_path: "Experiment(samples)>Sample"

0 comments on commit 51d2e1e

Please sign in to comment.