Domain Runtime Validation¶
Runtime domain validation provides best-effort semantic checks on OMOP objects during interactive or analytical use.
These checks answer a simple but critical question:
“Does this object reference concepts from the domains it claims to?”
Domain validation is advisory¶
Runtime validation in OMOP Alchemy is:
- non-blocking
- non-mutating
- safe to run interactively
- safe to skip entirely
It is designed to surface issues, not enforce policy.
This makes it suitable for:
- notebooks
- exploratory analysis
- cohort debugging
- governance and QA workflows
DomainValidationMixin¶
Domain runtime validation is provided via DomainValidationMixin,
which is intended for View classes only.
DomainValidationMixin
Adds lightweight runtime domain validation to OMOP View classes.
This mixin enables best-effort semantic checks that verify whether referenced concept IDs belong to expected OMOP domains.
Validation is advisory:
- no exceptions are raised
- no data is mutated
- detached objects are handled safely
Intended for View classes only.
Examples:
Specification on a View:
>>> class PersonView(Person, DomainValidationMixin):
>>> __expected_domains__ = {
>>> "gender_concept_id": ExpectedDomain("Gender"),
>>> "race_concept_id": ExpectedDomain("Race"),
>>> "ethnicity_concept_id": ExpectedDomain("Ethnicity"),
>>> }
Runtime usage:
>>> p = session.get(PersonView, 123)
>>> p.is_domain_valid
True
Violations can be inspected without raising exceptions:
>>> p.domain_violations
["gender_concept_id not in domain(s): ['Gender']"]
domain_violations
property
¶
domain_violations: list[str]
Human-readable descriptions of domain violations on this object.
is_domain_valid
property
¶
is_domain_valid: bool
Whether this object satisfies all declared domain expectations.
collect_domain_rules
classmethod
¶
collect_domain_rules() -> list[DomainRule]
Collect declared domain expectations as canonical DomainRule objects.
Returns:
| Type | Description |
|---|---|
list[DomainRule]
|
Domain rules derived from |
The mixin relies on:
- declared expectations
- an active SQLAlchemy session (if available)
- the OMOP
Concepttable
Runtime checking behavior¶
At runtime, domain validation:
- resolves referenced concept IDs
- checks their
domain_id - compares against expected domains
- reports violations as human-readable messages
OMOP conventions are respected:
concept_id = 0is always treated as valid- detached objects are handled safely
Example usage¶
p = session.get(PersonView, 123)
p.is_domain_valid
Returns True or False.
To inspect violations directly:
p.domain_violations
Example output:
[
"gender_concept_id not in domain(s): ['Gender']"
]
What happens under the hood¶
For each declared field:
- The referenced
concept_idis retrieved - The corresponding Concept row is resolved
- The concept’s
domain_idis compared - Violations are accumulated, not raised
When not to use runtime validation¶
Runtime validation is not a substitute for:
- ETL quality checks
- database constraints
- DataQualityDashboard or similar systematic QA tooling
Those tools operate at a different layer, with different goals. It complements those tools by operating at the model and object layer.
“Does this object, in this analytical context, behave the way I think it does?”
That’s a much more local question, and one that usually arises:
- during exploration
- while building derived views
- or when debugging unexpected analytical results
i.e. not asking whether the database as a whole is valid but trying to understand whether the meaning of what you’re looking at holds.
Why an object-level approach helps¶
Many semantic problems don’t show up cleanly in ETL or database checks:
- a view joins concept IDs that are technically valid but conceptually incompatible
- a derived cohort quietly mixes domains in a way that undermines interpretation
- a field is populated, but with concepts that don’t make sense for this specific use
Custom DQD checks expressed in SQL can handle these local constraints requiring additional context, however these issues are often easiest to spot when you’re already holding the data in your hands. Runtime validation takes advantage of object mappings to support that task by making expectations explicit and inspectable.
- DQD establishes baseline trust in the dataset
- OMOP Alchemy helps maintain semantic clarity during analytical work
Next steps¶
...come back soon for LinkML support