Columns & Structural Mixins¶
OMOP Alchemy provides a small set of column helpers and mixins that encode recurring OMOP CDM patterns directly into ORM structure.
These utilities exist to:
- reduce boilerplate
- make OMOP semantics explicit
- keep table definitions readable
- align ORM structure with CDM specifications
They are structural, not analytical: they describe how data is shaped, not what it means.
Column helper functions¶
Column helpers wrap common OMOP column patterns into small, intention-revealing factory functions.
They are thin wrappers around sqlalchemy.orm.mapped_column
with defaults chosen to match the CDM Field-Level specifications.
Concept foreign keys¶
OMOP relies heavily on concept identifiers, with specific semantics around nullability and unknown values.
required_concept_fk
OMOP-required concept foreign key.
This pattern is used when the CDM requires a concept reference,
but allows an explicit “unknown” value (concept_id = 0).
Semantics:
- Must exist
- Unknown allowed (concept_id = 0)
- Matches CDM Field-Level spec
- foreign key to
concept.concept_id
Convenience wrappers¶
These helpers exist primarily for consistency and readability when defining large tables with many fields.
Structural mixins¶
Structural mixins encode table-level OMOP patterns that recur across multiple CDM tables.
PersonScoped
Used for tables that are fundamentally scoped to a person.
Encodes the standard person_id foreign key and indexing pattern.
ConceptTyped
Mixin for tables whose primary meaning is encoded by a concept_id.
Subclasses MUST define something_concept_id.
Not currently used, but intention to build out logic for generic EAV queries & timeline projections.
ValueMixin
Encodes the OMOP pattern where a value may be represented either numerically or categorically.
Structural guarantees:
- at least one value must be present
- enforced via a check constraint
- validated at assignment time
This helps when building generic tooling that needs to handle values flexibly but then normalise for analysis.
Examples:
>>> from omop_alchemy.cdm.model.clinical.measurement import Measurement
>>> m = Measurement()
>>> m.value_as_number = 42.0
>>> m.value_as_concept_id = None # OK
>>> m.value_as_number = None # Raises ValueError
DatedEvent
Mixin for tables with start/end date and datetime pairs.
This mixin does not enforce temporal logic (e.g. start ≤ end); it only defines the shape, but this may be integrated with the event timeline machinery in future.
HealthSystemContext
Encodes attribution to providers and visits.
Used across many clinical event tables to provide consistent join points into the health system structure.
Marker mixins¶
Some mixins exist purely to label intent. They do not add columns or behavior. We don't currently do anything with these.