Linkr
Accueil Ressources Outils Documentation Blog Démo
EN
  • Découverte d'OMOP
  • La communauté OHDSI
  • Le modèle OMOP CDM
  • Les vocabulaires OMOP
  • L'écosystème d'outils OHDSI
  • Construire un ETL OMOP
  • SQL — Niveau débutant
  • SQL — Niveau intermédiaire
  • SQL — Niveau avancé
3/9
20 min Boris Delange · 14/05/2026

Le modèle OMOP CDM

Découverte du modèle de données OMOP CDM v5.4 : grandes catégories de tables, conventions clés, dualité source/standard.

En résumé

OMOP CDM est un modèle de base de données relationnelle conçu pour rendre les données de santé interrogeables de la même façon dans tous les hôpitaux et toutes les bases qui l’adoptent. On y trouve une quarantaine de tables organisées en six grandes catégories — cliniques, système de santé, vocabulaires, économie de santé, éléments dérivés, métadonnées — toutes articulées autour d’un principe simple : tout événement clinique est rattaché à une personne et à une date. La version 5.4, stable depuis 2021, est aujourd’hui la version de référence dans la communauté OHDSI.

Ce que vous savez déjà

Les articles précédents de cette section ont posé le pourquoi d’OMOP (le projet initial, sa communauté, l’idée d’un format commun). Cet article ouvre le comment : à quoi ressemble concrètement le modèle lorsqu’on examine sa structure.

Pour suivre, il suffit de garder en tête quelques notions vues dans la section Comprendre les entrepôts de données de santé :

  • Une base de données relationnelle est une collection de tables reliées entre elles par des clés — des colonnes partagées dont la valeur identifie un même objet d’une table à l’autre (par exemple person_id, qui apparaît dans toutes les tables d’événements pour rattacher chaque ligne à un patient unique de la table PERSON). C’est exactement la logique décrite dans l’article Comment sont organisées les données de santé ?.
  • Les données de santé sont structurées au format long : une ligne par événement, des colonnes pour qualifier cet événement.
  • Les codes médicaux (CIM-10, SNOMED CT, LOINC…) sont conservés sous une forme standardisée pour permettre la comparabilité entre bases.

OMOP CDM applique ces principes de manière rigoureuse : un schéma relationnel précisément spécifié, identique d’une institution à l’autre. C’est ce schéma que nous détaillons à partir d’ici.

Une brève histoire des versions

Le Common Data Model n’est pas figé : il évolue par versions, publiées par OHDSI sur GitHub. Connaître l’historique aide à comprendre la version qu’on utilise — et celles qu’on évite.

5.3

CDM v5.3 — janvier 2019

Version stable pendant deux ans et demi, qui a servi de socle à beaucoup d’entrepôts OMOP mis en place pendant cette période. Encore présente dans des bases qui n’ont pas migré vers la 5.4.

5.4

CDM v5.4 — septembre 2021

Version actuelle

Apporte les tables EPISODE et EPISODE_EVENT, intègre COHORT dans le modèle, et ajoute plusieurs champs aux tables existantes (coordonnées géographiques dans LOCATION, etc.). La liste complète des changements est documentée ici. C’est la version de référence aujourd’hui — stable depuis plus de quatre ans, ce qui est une force du modèle.

6.0

CDM v6.0 — octobre 2021, mise en pause

Cette version rendait obligatoires les champs datetime (heure précise) là où ils étaient auparavant optionnels. Le README officiel indique que v6.0 « n’est pas pleinement supporté par les outils et méthodes OHDSI » et recommande explicitement aux institutions de rester sur v5.4 le temps que la communauté tranche le rôle des dates par rapport aux datetime.

5.5

CDM v5.5 — prévue pour août 2026

Une évolution incrémentale est en préparation, suivie publiquement dans le milestone GitHub officiel, échéance août 2026. Au menu, entre autres : une nouvelle table PACK_CONTENT qui décrit la composition des packs de médicaments (quels principes actifs, en quelle quantité, dans quel conditionnement), un champ VALUE_AS_DATE dans OBSERVATION, et plusieurs corrections de clés étrangères. Nous mettrons cet article à jour quand la version sera publiée.

Les grandes catégories de tables

Le CDM v5.4 organise sa quarantaine de tables en six grandes catégories. Toutes ne sont pas utilisées dans toutes les bases : la plupart des entrepôts hospitaliers se concentrent sur les données cliniques et le système de santé.

Données cliniques standardisées

Les patients eux-mêmes, leurs hospitalisations, diagnostics, médicaments, examens biologiques et gestes médicaux. C’est le cœur du modèle, ce qui est observé sur les patients.

Vocabulaires standardisés

Le dictionnaire des concepts médicaux : codes, libellés, relations entre concepts et hiérarchies. Sujet de l’article suivant.

Système de santé standardisé

Le contexte de soin : les services hospitaliers, les professionnels de santé, et les lieux géographiques où les soins ont eu lieu.

Éléments dérivés standardisés

Des agrégations pré-calculées à partir des données cliniques, conçues pour accélérer les analyses récurrentes (par exemple regrouper plusieurs prescriptions successives en une période d’exposition continue).

Économie de la santé standardisée

Les coûts et remboursements associés aux soins, principalement renseignés dans les bases d’assurance maladie.

Métadonnées standardisées

La description de l’entrepôt lui-même : version du CDM utilisée, périmètre couvert, informations techniques sur l’instance.

L'explorateur interactif

Pour voir le détail de chaque table (colonnes, types de données, clés primaires et étrangères, contraintes), utilisez notre explorateur interactif du schéma OMOP v5.4. Il couvre l’ensemble des tables du modèle, avec des renvois entre elles.

Trois conventions fondamentales

Avant de plonger dans les tables une à une, trois principes structurent tout le modèle. Les comprendre vous fera gagner beaucoup de temps en pratique.

1. Modèle centré patient

Chaque enregistrement, dans toutes les tables d’événements, est associé à un identifiant patient (person_id) et à au moins une date. C’est la garantie que toute analyse peut produire une vue longitudinale de la santé d’un patient.

Les domaines sont modélisés dans un schéma relationnel centré patient, où chaque enregistrement comporte au minimum l’identité de la personne et une date.

— Book of OHDSI, section 4.1 Design Principles

2. Dualité source / standard

C’est probablement la convention OMOP la plus importante à comprendre. Pour chaque événement clinique, le modèle conserve deux représentations en parallèle :

  • Le code source original tel qu’il existe dans le système hospitalier (par exemple un code CIM-10 pour un diagnostic).
  • Le concept standardisé OMOP vers lequel ce code source a été mappé (par exemple le concept SNOMED CT équivalent).

Concrètement, chaque table d’événements suit le même patron de colonnes :

- <event>_concept_id        : identifiant du concept standard OMOP
- <event>_source_value      : code/libellé source tel quel
- <event>_source_concept_id : concept OMOP correspondant au code source

Exemple concret — une fréquence cardiaque dans MEASUREMENT

Imaginons que le moniteur d’un service de réanimation enregistre la fréquence cardiaque sous le libellé local « FC bpm », sans code structuré. Voici à quoi ressemble la ligne après l’ETL OMOP :

ColonneValeurLecture
measurement_concept_id3027018Le concept standard OMOP pour Heart rate (mappé sur LOINC 8867-4).
measurement_source_valueFC bpmLe libellé tel qu’il existait dans le système source, conservé pour la traçabilité.
measurement_source_concept_id0« FC bpm » n’est pas un code structuré reconnu : aucun concept source à attacher, donc 0.

Si la source avait utilisé directement le code LOINC 8867-4, alors measurement_source_concept_id aurait également valu 3027018 : LOINC étant un vocabulaire standard d’OMOP, le code source et le concept standard coïncident.

Pourquoi cette double représentation ? Parce qu’elle permet à la fois la comparabilité internationale (via le concept standard) et la traçabilité (en conservant le code source original, on peut toujours vérifier la donnée à la source).

Concept_id = 0, le 'NULL' d'OMOP

Quand un code source n’a pas de mapping vers un concept standard, son <event>_concept_id vaut 0. C’est le « flavor of NULL » d’OMOP — il signale un concept non standardisé sans qu’on ait à filtrer les valeurs nulles SQL classiques. Les requêtes de qualité commencent souvent par compter les concept_id = 0.

3. Le type_concept_id : d’où vient cet enregistrement ?

Beaucoup de tables incluent une colonne <event>_type_concept_id. Attention au piège : ce n’est pas une catégorisation de l’événement lui-même, mais une indication de sa provenance.

Par exemple, pour un médicament dans DRUG_EXPOSURE, le drug_type_concept_id indique si la donnée vient d’une prescription, d’une dispensation ou d’une administration — pas la nature du médicament.

C’est utile pour la qualité : on peut vouloir restreindre une analyse aux médicaments effectivement dispensés ou administrés, pas seulement prescrits.

Ces trois conventions en tête, abordons maintenant les principales tables du modèle. Nous les regroupons en deux familles : d’abord celles qui décrivent le patient et son parcours dans le système de soins, puis celles qui décrivent les événements cliniques observés au fil de ce parcours.

Le patient et son parcours

PERSON — la table des patients

Rôle :
Démographie du patient (sexe, année de naissance, origine).
Une ligne par :
Patient unique dans la base.
Connectée à :
Toutes les tables cliniques via person_id. C’est le point d’ancrage du modèle.

Tout commence par PERSON. C’est la table de démographie : une ligne par patient unique dans la base.

ColonneContenu
person_idIdentifiant unique du patient (clé primaire)
gender_concept_idSexe sous forme de concept standard OMOP
year_of_birthAnnée de naissance (seul champ obligatoire pour la date de naissance)
month_of_birth, day_of_birthOptionnels, selon ce qui est disponible à la source
race_concept_id, ethnicity_concept_idCatégories démographiques standardisées
location_id, provider_id, care_site_idLiens vers les tables de contexte

Notez la nuance entre year_of_birth (obligatoire) et month_of_birth/day_of_birth (optionnels). Le modèle accepte qu’une date de naissance soit partiellement connue — c’est fréquent dans les bases de remboursement.

Aperçu de la table

Trois patients distincts, chacun avec son identifiant person_id. Deux femmes et un homme, nés entre 1958 et 1985. Pour la patiente 1042, on connaît la date de naissance complète (12 avril 1958).

person_idgender_concept_idyear_of_birthmonth_of_birthday_of_birth
10428532 (Female)1958412
10438507 (Male)1972NULLNULL
10448532 (Female)1985NULLNULL

VISIT_OCCURRENCE — les contacts avec le système de santé

Rôle :
Décrit chaque contact du patient avec le système de soins (hospitalisation, consultation, urgence…).
Une ligne par :
Visite (un même patient en a généralement plusieurs au fil du temps).
Connectée à :
PERSON, CARE_SITE, et toutes les tables d’événements cliniques qui la référencent via visit_occurrence_id.

Chaque contact du patient avec le système de soins (hospitalisation, consultation externe, urgence…) génère une ligne dans VISIT_OCCURRENCE.

ColonneContenu
visit_occurrence_idIdentifiant unique de la visite
person_idLe patient concerné
visit_concept_idType de visite (hospitalisation, urgence, consultation…)
visit_start_date, visit_end_dateBornes temporelles
care_site_idService ou établissement
visit_source_valueLibellé source de la visite

Aperçu de la table

Trois visites pour deux patients. La patiente 1042 a été hospitalisée une semaine en mars puis revue en consultation externe deux mois plus tard. Le patient 1043, lui, est passé aux urgences sans hospitalisation (visite d’une journée).

visit_occurrence_idperson_idvisit_concept_idvisit_start_datevisit_end_datecare_site_id
7820110429201 (Inpatient Visit)2022-03-142022-03-2112
7820210429202 (Outpatient Visit)2022-05-022022-05-0247
7820310439203 (Emergency Room Visit)2023-11-082023-11-088

VISIT_DETAIL — les séjours par unité dans une hospitalisation

Rôle :
Découpe une hospitalisation en séjours par unité : urgences, réanimation, médecine, chirurgie…
Une ligne par :
Séjour dans une unité (une hospitalisation longue en génère plusieurs).
Connectée à :
VISIT_OCCURRENCE (le séjour parent), PERSON, et CARE_SITE.

Lors d’une hospitalisation, un patient peut transiter par plusieurs services : urgences à l’arrivée, réanimation, puis service de médecine pour la suite. VISIT_DETAIL capture ces étapes intermédiaires, chaque ligne pointant vers la visit_occurrence_id du séjour parent — on garde ainsi une vue d’ensemble tout en pouvant analyser chaque passage en unité.

ColonneContenu
visit_detail_idIdentifiant unique du sous-séjour
visit_occurrence_idLien vers la visite parente
person_idLe patient
visit_detail_concept_idType de sous-séjour (réanimation, hospitalisation classique…)
visit_detail_start_date, visit_detail_end_dateBornes temporelles
care_site_idService précis (médecine, chirurgie, cardiologie…)
parent_visit_detail_idPour modéliser des sous-séjours hiérarchisés

Aperçu de la table — décomposition du séjour 78201

Le séjour 78201 de la patiente 1042 (hospitalisation d’une semaine) est ici décomposé en trois sous-séjours : un passage aux urgences le jour de l’admission, trois jours en réanimation, puis quatre jours en médecine. Toutes ces lignes pointent vers la même visit_occurrence_id.

À noter : OMOP standardise peu les unités hospitalières — seule la réanimation a un concept dédié (32037 Intensive Care). Pour les autres séjours hospitaliers, on retombe sur le concept générique 9201 Inpatient Visit, et le service précis est porté par care_site_id.

visit_detail_idvisit_occurrence_idperson_idvisit_detail_concept_idvisit_detail_start_datevisit_detail_end_datecare_site_id
910017820110429203 (Emergency Room Visit)2022-03-142022-03-148
9100278201104232037 (ICU)2022-03-142022-03-1723
910037820110429201 (Inpatient Visit)2022-03-172022-03-2112

Les événements cliniques

Liens systématiques vers le parcours patient

Toutes les tables d’événements cliniques qui suivent (MEASUREMENT, OBSERVATION, CONDITION_OCCURRENCE, PROCEDURE_OCCURRENCE, DRUG_EXPOSURE) contiennent les mêmes clés étrangères vers le parcours du patient : person_id (vers PERSON), visit_occurrence_id (vers VISIT_OCCURRENCE) et visit_detail_id (vers VISIT_DETAIL). C’est ce qui permet, en quelques jointures, de remonter de n’importe quel événement à son patient, son séjour, et l’unité où il a eu lieu.

MEASUREMENT — les valeurs quantifiables

Rôle :
Stocke les valeurs cliniques quantifiables : résultats de biologie, signes vitaux, scores cliniques.
Une ligne par :
Mesure enregistrée (un même paramètre est mesuré plusieurs fois pendant un séjour).
Connectée à :
PERSON, VISIT_OCCURRENCE, VISIT_DETAIL, et au vocabulaire LOINC côté standard.

MEASUREMENT contient tout ce qui se mesure avec une valeur — chiffre, intervalle, résultat catégoriel codé.

ColonneContenu
measurement_idIdentifiant unique de la mesure
person_idLe patient
measurement_concept_idConcept standard (LOINC le plus souvent)
measurement_date, measurement_datetimeDate (et heure si disponible) de la mesure
value_as_numberValeur numérique
value_as_concept_idValeur codée (pour les résultats qualitatifs : positif/négatif, etc.)
unit_concept_idUnité de la valeur
range_low, range_highBornes de référence pour la mesure
visit_occurrence_id, visit_detail_idContexte de la mesure
measurement_source_valueLibellé source

Aperçu de la table

Trois mesures prises pour la patiente 1042 pendant son hospitalisation : une fréquence cardiaque (88/min), une température en fièvre légère (38,6 °C), et une urée sanguine. Chaque ligne associe un concept LOINC à sa valeur numérique et son unité.

measurement_idperson_idmeasurement_concept_idmeasurement_datevalue_as_numberunit_concept_id
22084110423027018 (Heart rate)2022-03-14888541 (/min)
22084210423020891 (Body temperature)2022-03-1438.6586323 (°C)
22084310423013682 (Urea nitrogen)2022-03-157.28753 (mmol/L)

OBSERVATION — les faits cliniques sans valeur numérique

Rôle :
Stocke les faits cliniques sans valeur numérique naturelle : signes cliniques, mode de vie, motif de consultation.
Une ligne par :
Fait clinique observé pour un patient.
Connectée à :
PERSON, VISIT_OCCURRENCE, VISIT_DETAIL, et SNOMED CT le plus souvent.

OBSERVATION accueille les événements cliniques qui ne trouvent leur place dans aucune autre table de domaine : statut tabagique, profession, motif de consultation, antécédents familiaux, score qualitatif, exposition environnementale… Quand un concept n’appartient pas aux domaines Condition, Drug, Procedure ou Measurement, c’est ici qu’il atterrit.

ColonneContenu
observation_idIdentifiant unique de l’observation
person_idLe patient
observation_concept_idConcept standard (SNOMED CT le plus souvent)
observation_date, observation_datetimeDate (et heure si disponible) de l’observation
value_as_numberValeur numérique si pertinente
value_as_stringValeur textuelle (réponse libre)
value_as_concept_idValeur codée
qualifier_concept_idPrécision sur l’observation
visit_occurrence_id, visit_detail_idContexte
observation_source_valueLibellé source

Une question fréquente : où va telle ou telle donnée — MEASUREMENT ou OBSERVATION ? La règle officielle est que le domaine du concept détermine la table : un concept de domaine Measurement va dans MEASUREMENT, un concept de domaine Observation dans OBSERVATION. ATHENA donne le domaine de chaque concept.

Aperçu de la table

Trois faits cliniques sans valeur numérique : un statut tabagique pour la patiente 1042 (Yes), un autre, plus nuancé, pour le patient 1043 (ancien fumeur), et le motif de consultation de la patiente 1044 (check-up). La colonne value_as_string stocke ici la réponse en texte.

observation_idperson_idobservation_concept_idobservation_datevalue_as_string
404001104240766306 (Smoked ≥ 100 cig.)2022-03-14Yes
404002104343054909 (Tobacco smoking status)2023-11-08Former smoker
40400310443025141 (Reason for visit)2024-02-19Routine check-up

CONDITION_OCCURRENCE — les diagnostics

Rôle :
Recense les diagnostics posés pour un patient (principal, comorbidités, liste de problèmes…).
Une ligne par :
Diagnostic enregistré (une visite peut générer plusieurs lignes).
Connectée à :
PERSON, VISIT_OCCURRENCE, VISIT_DETAIL, et aux vocabulaires (SNOMED CT côté standard, CIM-10 côté source).

Chaque diagnostic posé pour un patient devient une ligne dans CONDITION_OCCURRENCE. Une admission peut générer plusieurs lignes (un diagnostic principal + plusieurs comorbidités).

ColonneContenu
condition_occurrence_idIdentifiant unique du diagnostic
person_idLe patient
condition_concept_idConcept standard (SNOMED CT le plus souvent)
condition_start_dateDate de début
condition_end_dateDate de fin si connue (chronique ou résolu)
visit_occurrence_idLien vers la visite associée
condition_source_valueCode source (souvent CIM-10)
condition_source_concept_idConcept correspondant au code source
condition_type_concept_idProvenance : diagnostic principal, comorbidité, liste de problèmes…

Aperçu de la table

Trois diagnostics. La patiente 1042 a un diabète de type 2 connu depuis 2019 et une HTA diagnostiquée pendant son hospitalisation de 2022. Le patient 1043 a fait un infarctus en novembre 2023. Chaque ligne illustre la dualité source/standard : le concept SNOMED CT standard (condition_concept_id), le code CIM-10 source brut (condition_source_value) et son concept OMOP correspondant (condition_source_concept_id) sont conservés en parallèle.

condition_occurrence_idperson_idcondition_concept_idcondition_start_datevisit_occurrence_idcondition_source_valuecondition_source_concept_id
6012011042201826 (T2 diabetes)2019-06-2278101E11.945561952 (ICD10 E11.9)
6012021042320128 (Essential HTN)2022-03-1478201I1045591453 (ICD10 I10)
60120310434329847 (Myocardial inf.)2023-11-0878203I21.445572081 (ICD10 I21.4)

PROCEDURE_OCCURRENCE — les actes médicaux

Rôle :
Recense les gestes médicaux réalisés sur le patient : interventions chirurgicales, examens d’imagerie, gestes techniques, etc.
Une ligne par :
Acte enregistré.
Connectée à :
PERSON, VISIT_OCCURRENCE, VISIT_DETAIL, et aux vocabulaires (SNOMED CT côté standard, CCAM ou CPT-4 côté source selon le pays).

PROCEDURE_OCCURRENCE documente tout ce qu’on fait au patient, par opposition à ce qu’on observe chez lui (CONDITION_OCCURRENCE) ou ce qu’on lui donne (DRUG_EXPOSURE).

ColonneContenu
procedure_occurrence_idIdentifiant unique de l’acte
person_idLe patient
procedure_concept_idConcept standard (SNOMED CT le plus souvent)
procedure_date, procedure_datetimeDate (et heure si disponible) de l’acte
procedure_end_date, procedure_end_datetimeDate (et heure) de fin, pour les actes qui durent
visit_occurrence_id, visit_detail_idContexte
quantityNombre d’actes
procedure_source_valueCode source (CCAM en France, CPT-4 aux US, ICD-10-PCS…)
procedure_source_concept_idConcept correspondant au code source
procedure_type_concept_idProvenance de l’enregistrement

Aperçu de la table

Trois actes médicaux. Pour les deux premiers — l’appendicectomie de la patiente 1042 et la séance d’hémodialyse du patient 1043 — on dispose des heures précises de début et de fin (champs datetime), ce qui permet de calculer la durée de l’acte. La prise de sang de la patiente 1044, plus brève, n’a pas d’heure de fin renseignée. Le procedure_source_value conserve le code source (CCAM en France).

procedure_occurrence_idperson_idprocedure_concept_idprocedure_datetimeprocedure_end_datetimevisit_occurrence_idprocedure_source_value
81050110424198190 (Appendectomy)2022-03-15 09:302022-03-15 11:0078201HHFA002
810502104337397396 (Hemodialysis)2023-11-09 08:002023-11-09 12:1578203JVJF002
81050310444332170 (Venipuncture)2024-02-19 09:15NULL78305HSHF002

DEVICE_EXPOSURE — les dispositifs médicaux

Rôle :
Recense l’exposition du patient à un objet physique utilisé à des fins diagnostiques ou thérapeutiques : implants (stents, prothèses), matériel de soin (cathéters, sondes), consommables (seringues, bandages).
Une ligne par :
Exposition à un dispositif.
Connectée à :
PERSON, VISIT_OCCURRENCE, VISIT_DETAIL, et au vocabulaire SNOMED CT côté standard (domaine Device).

DEVICE_EXPOSURE stocke ce qu’on applique au patient quand il s’agit d’un objet physique — par opposition à un médicament (DRUG_EXPOSURE) ou à un geste (PROCEDURE_OCCURRENCE). La frontière avec PROCEDURE_OCCURRENCE peut être floue : la pose d’un stent est une procédure, mais le stent lui-même est un dispositif. Les deux tables coexistent souvent pour le même épisode de soin.

ColonneContenu
device_exposure_idIdentifiant unique de l’exposition
person_idLe patient
device_concept_idConcept standard (SNOMED CT, domaine Device)
device_exposure_start_date, device_exposure_end_datePériode d’exposition
unique_device_id, production_idUDI (Unique Device Identifier) FDA si disponible
quantityNombre de dispositifs utilisés
visit_occurrence_id, visit_detail_idContexte
device_source_valueLibellé ou code source
device_type_concept_idProvenance (remboursement, DPI…)

Aperçu de la table

Trois dispositifs. Pendant son passage en réanimation, la patiente 1042 a été équipée d’un cathéter veineux central (en place pendant trois jours) et d’une sonde urinaire. Le patient 1043 a reçu un stent coronaire pendant son passage aux urgences pour infarctus — un implant, sans date de fin.

device_exposure_idperson_iddevice_concept_iddevice_exposure_start_datedevice_exposure_end_datevisit_occurrence_id
11500110424160023 (Central venous catheter)2022-03-142022-03-1778201
11500210424047968 (Urinary catheter)2022-03-142022-03-1678201
11500310434252356 (Coronary artery stent)2023-11-08NULL78203

NOTE — les comptes-rendus en texte libre

Rôle :
Capture les documents en texte libre rédigés par les soignants : comptes-rendus d’hospitalisation, courriers de consultation, observations médicales, comptes-rendus opératoires…
Une ligne par :
Document texte produit pour un patient.
Connectée à :
PERSON, VISIT_OCCURRENCE, VISIT_DETAIL, PROVIDER (l’auteur), et au vocabulaire LOINC (Document Ontology) côté standard.

NOTE accueille les données non structurées : ce que les autres tables ne capturent pas parce que c’est de la rédaction libre. C’est la matière première du TAL (NLP en anglais), dont les résultats remontent ensuite dans une table dédiée NOTE_NLP.

ColonneContenu
note_idIdentifiant unique du document
person_idLe patient
note_date, note_datetimeDate (et heure si disponible) de rédaction
note_class_concept_idClassification LOINC du type de document (CR d’hospitalisation, lettre de sortie…)
note_titleTitre du document
note_textContenu intégral du document (texte)
encoding_concept_idEncodage des caractères (typiquement UTF-8)
language_concept_idLangue du document
provider_idAuteur du document
visit_occurrence_id, visit_detail_idContexte
note_type_concept_idProvenance (DPI, dictée, importation…)

Aperçu de la table

Trois notes produites pendant l’hospitalisation de la patiente 1042 : un compte-rendu d’admission rédigé aux urgences, un compte-rendu opératoire après l’appendicectomie, et une lettre de sortie. Le contenu intégral est dans note_text (tronqué ici pour l’affichage). Chaque ligne porte sa classification LOINC, qui permet de filtrer par type de document — par exemple toutes les lettres de sortie d’un service donné.

note_idperson_idnote_datenote_class_concept_idnote_titlevisit_occurrence_id
70010110422022-03-14706470 (Admission note)Observation d’entrée78201
70010210422022-03-15706526 (Operative note)CR opératoire — appendicectomie78201
70010310422022-03-21706473 (Discharge summary)Lettre de sortie78201

Exploiter le texte libre

Le texte brut de note_text est rarement utilisable tel quel pour une analyse : il faut le structurer. C’est le rôle du TAL (NLP en anglais) — extraction d’entités cliniques, de négations, de relations — dont les résultats vont dans NOTE_NLP, une ligne par terme extrait.

DRUG_EXPOSURE — les médicaments

Rôle :
Recense toutes les expositions médicamenteuses : prescriptions, dispensations en pharmacie, administrations à l’hôpital.
Une ligne par :
Exposition à un médicament (un même traitement chronique génère plusieurs lignes).
Connectée à :
PERSON, VISIT_OCCURRENCE, VISIT_DETAIL, et au vocabulaire RxNorm côté standard.

DRUG_EXPOSURE regroupe toutes les expositions médicamenteuses : prescriptions, dispensations, administrations à l’hôpital. Le drug_type_concept_id permet de distinguer ces provenances.

ColonneContenu
drug_exposure_idIdentifiant unique
person_idLe patient
drug_concept_idConcept standard (RxNorm le plus souvent)
drug_exposure_start_date, drug_exposure_end_datePériode d’exposition
quantity, days_supply, dose_unit_source_valuePosologie
route_concept_idVoie d’administration
drug_source_valueLibellé source
drug_type_concept_idType d’enregistrement (prescription, dispensation, etc.)

Aperçu de la table

Trois expositions médicamenteuses, de provenances différentes : une prescription de célécoxib pour la patiente 1042 à la sortie d’hospitalisation, une administration d’ibuprofène à l’hôpital le lendemain de l’appendicectomie, et une dispensation pharmacie d’un antalgique pour le patient 1043. Le drug_type_concept_id permet de distinguer ces trois cas.

drug_exposure_idperson_iddrug_concept_iddrug_exposure_start_datequantitydrug_type_concept_id
92030110421118084 (celecoxib)2022-03-153032838 (prescription)
920302104219078461 (ibuprofen 200 mg)2022-03-16132818 (administration)
920303104319133768 (paracetamol+hydrocodone)2023-11-102032825 (dispensing)

Calculer la dose réellement reçue

Une particularité d’OMOP : la dose de médicament prise par le patient n’est pas stockée directement dans DRUG_EXPOSURE. La colonne quantity donne seulement le nombre d’unités délivrées (comprimés, ampoules, millilitres…). Pour passer du nombre d’unités à la dose réelle en milligrammes, il faut joindre DRUG_EXPOSURE avec la table DRUG_STRENGTH, qui contient la concentration du principe actif pour chaque produit standard.

Exemple ambulatoire : un traitement sur plusieurs jours

Pour notre patiente 1042 et sa prescription de 30 comprimés de celecoxib 200 mg sur 7 jours (ligne 920301 de l’aperçu ci-dessus) :

  • DRUG_EXPOSURE.quantity = 30 (comprimés délivrés)
  • DRUG_STRENGTH.amount_value = 200 (mg par comprimé pour le produit standard)
  • DRUG_EXPOSURE.days_supply = 7 (jours de traitement)

→ Dose totale : 30 × 200 = 6000 mg sur la période → Dose journalière : 6000 ÷ 7 ≈ 857 mg/jour (soit 1,5 comprimé/jour)

Exemple hospitalier : une perfusion IV à débit variable

En contexte hospitalier, surtout en réanimation, on a souvent une ligne par administration — voire une ligne par changement de débit pour les perfusions continues. C’est très différent du modèle ambulatoire : ici, ce sont les colonnes drug_exposure_start_datetime et drug_exposure_end_datetime qui portent l’information temporelle fine, à la minute près.

Imaginons la patiente 1042 pendant son passage en réanimation (sous-séjour 91002) sous noradrénaline IV (concept 37354531, concentration 0,128 mg/mL = 128 µg/mL). Trois changements de débit sur l’après-midi :

drug_exposure_start_datetimedrug_exposure_end_datetimequantity (mL perfusés)
2022-03-14 13:372022-03-14 14:012,0
2022-03-14 14:012022-03-14 16:2027,8
2022-03-14 16:202022-03-14 18:3017,3

Chaque ligne représente une période de débit stable (le débit n’est pas stocké tel quel — on le déduit de la quantité perfusée divisée par la durée entre start_datetime et end_datetime). La dose réellement administrée se reconstitue ensuite en multipliant le volume perfusé (quantity) par la concentration du produit (numerator_value / denominator_value dans DRUG_STRENGTH).

→ Sur la ligne du milieu (27,8 mL à 0,128 mg/mL) : 3,56 mg de noradrénaline délivrés en 2h19, soit environ 1,5 mg/h.

Pour une analyse sur tout un séjour de réanimation, il faut donc sommer toutes ces lignes par patient et par médicament, en tenant compte de la durée de chaque débit.

Quelle formule selon la forme du médicament ?

La règle de calcul change selon la forme galénique :

  • Comprimé, gélule, ampoule unitaire : quantity × amount_value
  • Solution, perfusion, suspension : quantity × numerator_value / denominator_value
  • Patch transdermique : on utilise le débit (numerator_value par unité de temps) plutôt qu’une quantité totale

Le détail des formules est dans la documentation officielle OMOP sur le calcul de dose. Nous reverrons DRUG_STRENGTH plus en détail dans l’article suivant sur les vocabulaires.

Passez à la pratique

Manipuler les données est de loin le meilleur moyen de s’approprier le modèle OMOP. Pour vous entraîner sur les tables que nous venons de détailler, nous avons préparé une série de tutoriels SQL interactifs, jouables directement dans le navigateur sur un échantillon OMOP réel — sans rien à installer :

  • Niveau débutant — premiers SELECT, premières jointures, compter des patients, filtrer par diagnostic.
  • Niveau intermédiaire — agrégations, fenêtres temporelles, exploitation de la dualité source/standard.
  • Niveau avancé — cohortes, requêtes multi-tables complexes, calculs de dose.

Pour aller plus loin

Cet article a couvert les tables centrales pour la pratique clinique. Les autres tables (PROVIDER, CARE_SITE, LOCATION, COST, SPECIMEN, EPISODE, NOTE_NLP…) suivent les mêmes principes.

  • L’explorateur interactif du schéma OMOP v5.4 donne le détail colonne par colonne de toutes les tables.
  • Le chapitre 4 du Book of OHDSI est la documentation officielle complète.
  • Les conventions précises (formats de date, contraintes, valeurs autorisées) sont décrites dans Themis, le référentiel officiel des conventions ETL d’OHDSI.
  • OMOP CDM est un modèle relationnel d'environ 40 tables, réparties en six catégories. La v5.4 est stable depuis 2021.
  • Trois conventions structurent tout le modèle : centré patient (person_id + date partout), dualité source/standard (concept_id vs source_value vs source_concept_id), et type_concept_id pour tracer la provenance de l'enregistrement.
  • concept_id = 0 signale un code source non mappé. C'est l'indicateur de qualité le plus simple à surveiller en premier.
  • PERSON est le point d'ancrage de tout le modèle ; VISIT_OCCURRENCE orchestre les contacts avec le système de soins ; VISIT_DETAIL capture les passages par unité (réa, médecine…).
  • Sept tables pour les événements cliniques, une par domaine : CONDITION_OCCURRENCE (diagnostics), DRUG_EXPOSURE (médicaments), PROCEDURE_OCCURRENCE (actes), MEASUREMENT (valeurs quantifiables), OBSERVATION (faits cliniques sans valeur naturelle), DEVICE_EXPOSURE (dispositifs médicaux) et NOTE (texte libre).
  • La dose réellement administrée n'est pas stockée dans DRUG_EXPOSURE : il faut joindre avec DRUG_STRENGTH.
  • Le détail colonne par colonne est dans l'explorateur interactif ; les conventions précises (dates, contraintes, valeurs autorisées) dans Themis. Et surtout : passez à la pratique avec les tutoriels SQL pour vraiment s'approprier le modèle.
PrécédentLa communauté OHDSISuivantLes vocabulaires OMOP

Produit

  • Accueil
  • Démo

Ressources

  • Documentation
  • Ressources
  • Outils
  • Blog

Communauté

  • Code source Framagit
  • Code source Github

À propos

  • InterHop.org
  • Contact

2021–2026 InterHop — CC BY-NC-SA 4.0 (site) · GPLv3 (logiciel)