MDF Enforced Validator and Loader

Logo

Documentation for MEVAL.

Validator Usage

meval/validator.py enforces MDF-based data quality checks on submission TSV files. Validation is split across three classes:

Contents

Instantiation

from bento_mdf import MDFReader
from meval.validator import LocalValidator, RemoteValidator

mdf = MDFReader("model.yml", "model-props.yml", handle="ccdi_dcc")
validator = LocalValidator(mdf)

validator.model exposes the underlying MDF model, and validator.record_validator is the bento_mdf.MDFDataValidator instance used for record-level checks.

RemoteValidator is not instantiated — its methods are called directly on the class, e.g. RemoteValidator.validate_tsv_in_db(...).

Local validation

ATTENTION: LocalValidator is used for submission files before UUID creation.

These methods only read TSV files and the MDF model — no database connection is required. They are instance methods on LocalValidator.

validate_tsv_format(file_path)

Validates the structural format of a single TSV file: presence of a type column, no missing/mixed type values, type is a valid node in the model, all required properties are present as columns, unknown property columns (warning), and relationship columns (<parent>.<parent_key_prop>) are valid and complete for the node type. Returns a list of error/warning dicts (empty list if the file is valid).

validate_tsv_files_format(file_path_list)

Runs validate_tsv_format over multiple files. Returns a dict of {file_path: [errors...]}, only including files that have at least one issue.

validate_tsv_records(file_path, subgraph_col=None, id_field=None, delimiter=";")

Validates each row’s property values (types, required-ness, permissible values) against the model using MDFDataValidator, one record at a time. Returns a list of {"row": int, "is_valid": bool, "messages": {...}} for invalid rows only.

validate_tsv_rels(file_path_list, rel_delimiter=";")

Validates relationship columns across a set of TSV files that belong to the same subgraph (e.g. all files for one study). For each relationship column, confirms the column itself is valid for the model, that every non-empty node has at least one relationship value, and that every relationship value matches an existing key-property value in the corresponding parent-type file(s). Must be run before UUID5 generation, since it matches on the natural key column (e.g. participant.participant_id), not guid. Returns {file_path: [issue...]}.

validate_tsv_uniq_entry(file_path_list)

Checks that key-property values are unique within each node type across a set of files from the same subgraph (duplicate key values under the same type + subgraph would collide to the same UUID5). Returns a list of duplicate-entry dicts.

files = validator.find_tsv_files("submission_folder")
format_errors = validator.validate_tsv_files_format(files)
uniq_errors = validator.validate_tsv_uniq_entry(files)
rel_errors = validator.validate_tsv_rels(files)
record_errors = validator.validate_tsv_records("participant.tsv")

Other local-validation helpers

ValidatorUtilities helpers (inherited by LocalValidator)

UUID generation

These are ValidatorUtilities static methods, inherited by both LocalValidator and RemoteValidator. They can be called on either class, e.g. LocalValidator.generate_uuid5(...).

generate_uuid5(project_name, subgraph_value, record_type, record_key_value, delimiter=";")

Deterministically generates a UUID5 from {subgraph_value}::{record_type}::{key_value}, namespaced by get_project_namespace(project_name) (an MD5-derived UUID from the project/commons name). If record_key_value contains the delimiter, each part is hashed separately and the delimiter-joined UUID string is returned (used for multi-valued relationship columns).

add_uuid_to_tsv_file(file_path, project_name, mdf, output_file_path, uuid_column="guid", delimiter=";", subgraph_value=None)

Reads a TSV file, generates a guid (or custom uuid_column) value for every record and for every relationship column (converting <parent>.<parent_key_prop> columns to <parent>.guid), then writes the result to output_file_path with the original relationship and subgraph columns removed. The subgraph value is taken from the subgraph column in the file unless explicitly passed via subgraph_value.

from meval.validator import ValidatorUtilities

ValidatorUtilities.add_uuid_to_tsv_file(
    file_path="participant.tsv",
    project_name="ccdi",
    mdf=mdf,
    output_file_path="participant_with_uuid.tsv",
)

get_project_namespace(project_name)

Returns the uuid.UUID namespace derived from md5(project_name), used internally by generate_uuid5.

Validation against an existing database

ATTENTION: Validation submission files against a database can only be performed after UUID creation.

These methods compare submission files against records already stored in the graph database, to project what would change on load and to catch relationship targets that don’t exist anywhere (neither in the database nor the submission set). They live on RemoteValidator, require a Neo4j/Memgraph driver, are all class methods (no instantiation needed), and are designed to run after UUID5 generation (matching is done on guid, not the natural key).

validate_tsv_in_db(driver, tsv_file_path, tsv_id_set, mdf_instance, id_prop_name, delimiter=";", validation_mode="Upsert")

The main entry point for DB validation of a single file. For each row it determines, based on validation_mode:

For every relationship in the row, it checks whether the destination node exists in the database or in the current submission set (tsv_id_set, built via build_tsv_id_set); if neither, the row fails with an invalid_edge_dst_node_not_found error. Returns a tuple (passed_row_list, failed_row_list, val_summary, validation_results), where val_summary includes projected_changes_of_passed_rows (counts of nodes/edges to be created, updated, or deleted).

from meval.validator import RemoteValidator

tsv_id_set = RemoteValidator.build_tsv_id_set(all_submission_files, id_field="guid")
passed, failed, summary, results = RemoteValidator.validate_tsv_in_db(
    driver=driver,
    tsv_file_path="participant_with_uuid.tsv",
    tsv_id_set=tsv_id_set,
    mdf_instance=mdf,
    id_prop_name="guid",
    validation_mode="Upsert",
)

Supporting DB-validation helpers

Notes