Data Quality Module
The data quality module lives atingestion/src/metadata/data_quality/. It runs test cases against database tables (or DataFrames) and publishes results back to the OpenMetadata server.
This guide walks through the architecture top-down: from how a workflow is triggered, through the execution pipeline, down to individual validators.
Directory Layout
Workflow Pipeline
Data quality follows the standard Source → Processor → Sink pattern defined inworkflow/data_quality.py:
Test Execution Call Chain
This is the most important sequence to understand. WhenTestCaseRunner processes a test case, here is exactly what happens:
Data Model
Three entities form the core model. All are defined as JSON Schemas inopenmetadata-spec/ and auto-generated into Python models:
Validator Architecture
Validators use a template method pattern with mixins for database-specific logic.Class Hierarchy
How Validators Are Discovered
Validators are dynamically imported at runtime based on thevalidatorClass field from the TestDefinition:
Dimensional Analysis
When a test case hasdimensionColumns configured, the validator runs the test per group using GROUP BY:
validations/impact_score.py) ranks which groups matter most:
failure_rate²— emphasizes high failure percentagesvolume_factor— tiered by row count (0.25 for <10 rows → 1.5 for ≥100k)sample_weight— credibility discount for small samples
Runtime Parameter Setters
Some tests need parameters that can only be resolved at execution time. TheRuntimeParameterSetterFactory (validations/runtime_param_setter/param_setter_factory.py) maps test definition names to setter classes:
Adding a New Test
1
Create the base validator
Create
validations/column/base/myNewTest.py (or table/base/ for table-level tests).Extend BaseTestValidator and implement:_run_validation()— core test logic_evaluate_test_condition()— return pass/fail_format_result_message()— human-readable result string
2
Create the SQLAlchemy implementation
Create
validations/column/sqlalchemy/myNewTest.py.Inherit from your base class and SQAValidatorMixin. The mixin gives you get_column(), run_query_results(), and _execute_dimensional_validation().3
Create the Pandas implementation
Create
validations/column/pandas/myNewTest.py.Inherit from your base class and PandasValidatorMixin.4
Register the TestDefinition
Create a
TestDefinition in OpenMetadata with:validatorClassmatching your file name (e.g.,"myNewTestValidator")entityTypeset toCOLUMNorTABLE- Parameter definitions for any inputs your test needs
No imports or registries need to be updated. The
ValidatorBuilder discovers your validator automatically from the file path convention.