Skip to content

Domain Rules

Domain rules describe expected OMOP concept domains for specific fields on OMOP tables or views.

They are represented explicitly using the DomainRule model.

These expectations are not enforced by the database and are often not enforced by ETL pipelines — which is precisely why they need to be documented and validated explicitly.


Declaring expected domains

DomainRule

Immutable specification of an expected OMOP domain constraint.

A DomainRule describes the semantic expectation that a given concept ID field on a table or view should reference concepts from one or more OMOP domains.

Domain rules are derived from model declarations and are intended for inspection, documentation, and validation workflows. They do not enforce behavior or mutate data.

Parameters:

Name Type Description Default
table str

Name of the OMOP table or view the rule applies to.

required
field str

Name of the concept ID field being constrained.

required
allowed_domains FrozenSet[str]

Set of OMOP domains that are considered valid.

required
allowed_classes Optional[set[str]]

Optional restriction to specific concept classes.

None

Why rules are generated, not authored

OMOP Alchemy does not encourage manually writing domain rules.

Instead, rules are derived from model declarations to ensure:

  • rules stay co-located with semantic intent
  • documentation cannot drift from code
  • tooling can introspect expectations automatically

Domain rules are collected from View classes that declare their expectations explicitly.

The ExpectedDomain Model

ExpectedDomain

Declares one or more expected OMOP domains for a concept field.

ExpectedDomain is used on View classes to express semantic intent.

Examples:

>>> ExpectedDomain("Gender").domains
frozenset({'Gender'})
>>> ExpectedDomain("Race", "Ethnicity").domains
frozenset({'Race', 'Ethnicity'})

Use on View Classes

Expected domains are declared on View classes using __expected_domains__.

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 __expected_domains__.


Collecting rules programmatically

Declared rules can be collected into canonical DomainRule objects:

PersonView.collect_domain_rules()

Which yields:

[
    DomainRule(
        table="person",
        field="gender_concept_id",
        allowed_domains={"Gender"},
    ),
    DomainRule(
        table="person",
        field="race_concept_id",
        allowed_domains={"Race"},
    ),
]

This allows domain rules to be:

  • documented
  • audited
  • exported
  • validated across the model layer

What domain rules are not

Domain rules intentionally do not:

  • enforce ETL behavior
  • mutate data
  • raise hard exceptions
  • assume any execution environment

They exist to make semantic expectations visible and checkable — not to constrain ingestion workflows.