MedicationDispense drug_exposure documented primary

Pharmacy dispensing events. One FHIR MedicationDispense produces one OMOP drug_exposure row with drug_type_concept_id = 38000175 (Prescription dispensed in pharmacy). Date is taken from whenHandedOver (fallback whenPrepared). End date is computed from start + daysSupply, or defaults to start date. No reviewed reference implementation covers this mapping; the spec is reconstructed from OMOP drug_exposure schema and FHIR R4 MedicationDispense definition.

A FHIR instance converts to drug_exposure iff it validates against this profile.
Path Card Type Binding / Fixed Comment
MedicationDispense.status 1..*MS fhir/medicationdispense-statusrequired
MedicationDispense.medication[x] 1..*MS CodeableConcept omop-drug-codesrequired
MedicationDispense.subject 1..1 Reference Required for drug_exposure.person_id.
MedicationDispense.whenHandedOver 1..1MS Required for drug_exposure.drug_exposure_start_date. Falls back to whenPrepared only when whenHandedOver is absent — this profile requires whenHandedOver for OMOP-grade conversion.
ViewDefinition (Stage 1 flattener) omop-medicationdispense-drug-exposure
18 columns · resource MedicationDispense
column name FHIRPath type
id MedicationDispense.id id
drug_rxnorm MedicationDispense.medicationCodeableConcept.coding.where(system='http://www.nlm.nih.gov/research/umls/rxnorm').first().code code
drug_ndc MedicationDispense.medicationCodeableConcept.coding.where(system='http://hl7.org/fhir/sid/ndc').first().code code
drug_atc MedicationDispense.medicationCodeableConcept.coding.where(system='http://www.whocc.no/atc').first().code code
drug_snomed MedicationDispense.medicationCodeableConcept.coding.where(system='http://snomed.info/sct').first().code code
drug_text MedicationDispense.medicationCodeableConcept.text string
subject_id MedicationDispense.subject Reference(Patient)
drug_exposure_start_date MedicationDispense.whenHandedOver dateTime
drug_exposure_start_datetime MedicationDispense.whenHandedOver dateTime
drug_exposure_end_date MedicationDispense.daysSupply Duration
quantity MedicationDispense.quantity.value decimal
days_supply MedicationDispense.daysSupply.value integer
sig MedicationDispense.dosageInstruction[].text string
route MedicationDispense.dosageInstruction[].route CodeableConcept
route_text MedicationDispense.dosageInstruction[].route.text string
performer_id MedicationDispense.performer[0].actor Reference(Practitioner | PractitionerRole | Organization)
encounter_id MedicationDispense.context Reference(Encounter)
dose_unit_text MedicationDispense.dosageInstruction[].doseAndRate[].doseQuantity.unit string
Condition: status != 'entered-in-error' AND status != 'cancelled' AND status != 'declined' AND status != 'stopped'

Fields (23)

  • drug_exposure_id integer · id
    PKrequired
    Surrogate key, generated deterministically from MedicationDispense.id
  • person_id MedicationDispense.subject integer · Reference(Patient)
    FK→PERSONrequired
    Resolve Patient reference to person_id
  • drug_concept_id MedicationDispense.medication[x] integer · CodeableConcept | Reference(Medication)
    FK→CONCEPTrequiredmap:drug
    RxNorm / ATC / NDC -> OMOP standard concept. Resolve medicationCodeableConcept or medicationReference
  • drug_exposure_start_date MedicationDispense.whenHandedOver date · dateTime
    required
    transform:date(whenHandedOver ?? whenPrepared)
    The date medication was supplied. Fallback to whenPrepared if whenHandedOver absent
  • drug_exposure_start_datetime MedicationDispense.whenHandedOver datetime · dateTime
    transform:whenHandedOver ?? whenPrepared
    Full ISO datetime
  • drug_exposure_end_date MedicationDispense.daysSupply date · Duration
    required
    transform:date(start + daysSupply) ?? start_date
    If daysSupply present: end = start + daysSupply. Otherwise fallback to start date
  • drug_exposure_end_datetime datetime · dateTime
    Null if no daysSupply
  • verbatim_end_date date · date
    Leave null. MedicationDispense does not carry a verbatim end date
  • drug_type_concept_id constant integer · integer
    FK→CONCEPTrequired=38000175
    Prescription dispensed in pharmacy. Alternative: 32817 (EHR) used by FhirToCdm/ETL-German for other medication resources
    2 sources ▾
  • stop_reason varchar(20) · string
    Leave null. MedicationDispense does not carry a discontinuation reason
  • refills integer · integer
    Leave null. Refills are tracked on the originating MedicationRequest, not the dispense
  • quantity MedicationDispense.quantity.value float · decimal
    Dispensed quantity (the total handed over)
  • days_supply MedicationDispense.daysSupply.value integer · integer
    Days of medication supplied. Direct FHIR field on MedicationDispense (unlike MedicationRequest where it must be computed)
  • sig MedicationDispense.dosageInstruction[].text varchar(MAX) · string
    Free-text dosage instructions. Fallback to patientInstruction
  • route_concept_id MedicationDispense.dosageInstruction[].route integer · CodeableConcept
    FK→CONCEPTmap:route
    SNOMED route codes -> OMOP Route domain
  • route_source_value MedicationDispense.dosageInstruction[].route.text varchar(50) · string
    Raw route text or coding[0].display
  • lot_number varchar(50) · string
    Not used for MedicationDispense
  • provider_id MedicationDispense.performer[0].actor integer · Reference(Practitioner | PractitionerRole | Organization)
    FK→PROVIDER
    The dispensing pharmacist or actor
  • visit_occurrence_id MedicationDispense.context integer · Reference(Encounter)
    FK→VISIT_OCCURRENCE
    Encounter reference. Resolve to visit_occurrence_id
  • visit_detail_id integer · integer
    FK→VISIT_DETAIL
    Leave null
  • drug_source_value MedicationDispense.medication[x].coding[best].code varchar(50) · code
    Best code by vocabulary priority (RxNorm > ATC > NDC > SNOMED)
  • drug_source_concept_id MedicationDispense.medication[x] integer · integer
    FK→CONCEPT=0
    Source vocabulary concept. Placeholder: 0
  • dose_unit_source_value MedicationDispense.dosageInstruction[].doseAndRate[].doseQuantity.unit varchar(50) · string
    Raw dose unit string from doseQuantity.unit or .code

Vocabularies

drug_type

Source Display Concept ID Concept Name
MedicationDispense Pharmacy dispense event 38000175 Prescription dispensed in pharmacy
MedicationDispense (EHR variant) EHR-based type used by FhirToCdm/ETL-German 32817 EHR

Edge Cases

status = 'entered-in-error'
Skip -- do not create drug_exposure row. Consensus across implementations for all medication resources.
status = 'cancelled' / 'declined' / 'stopped'
Skip. No reference implementation precedent for MedicationDispense specifically. Recommended: skip non-completed dispenses.
whenHandedOver absent, whenPrepared present
Use whenPrepared as drug_exposure_start_date.
Both whenHandedOver and whenPrepared absent
Fallback to context (encounter) start date, or null. Consider dropping the record if no date can be resolved.
daysSupply absent
End date = start date. days_supply column left null.
quantity absent
Leave quantity column null.
Multiple dosageInstruction entries
Take first entry. Consistent with handling in other medication resources (MedicationRequest, MedicationStatement).
Cross-reference to originating MedicationRequest via authorizingPrescription
Currently no implementation links these for OMOP. Could be used to inherit dosage/refill metadata in future.
Medication resolution: medicationReference to contained or external Medication
Resolve contained Medication inline. For external references, look up by reference. Most implementations handle inline medicationCodeableConcept only.
Multiple codings on medication[x]
Pick best by vocabulary priority: RxNorm > ATC > NDC > SNOMED.
drug_source_value truncation
OMOP varchar(50) limit. Truncate to 50 characters.

Reference Implementations