Data Model (OpenMRS Implementer Meeting 2010)

Objectives:

  • Learn about the data model
  • ... how concepts are related to other things
  • ... how to extend the data model
  • ... more about drug orders and encounters
  • "As an implementer, sometimes I don't understand why the programmers did things the way they did. I'd like to learn."
  • ... how to deal with mental health data (lots of free text)
  • ... so I can write better SQL queries
  • Push towards better documentation
  • ... how much am I (i.e. Baobab) abusing it now?
  • ... and learn what changes are coming
  • ... more about problem lists and allergies
  • ... how to manipulate the data

Notes

  • See an image of the data model on the OpenMRS wiki, under Developer Documentation
    • Broken down into domains (by color on the image)
  • Encounters
    • started off representing a visit, filled out from a form
    • we are growing beyond this
    • Encounters have types (e.g. initial visit, return visit, ...)
    • ... link to a form (that was used to fill out the encounter)
    • ... take place at a location (i.e. a physical, geographic location)
    • ... have a timestamp
    • Upcoming change in 1.9: adding 'Visit' to the data model, which can group multiple encounters
      • Visits will have a start date and an end date
    • Upcoming change (after 1.9): adding 'Episodes of Care' which can group multiple encounters and visits
      • lots of overlap with program enrollments, workflows, and states
  • "Tags": this term to refer to "folksonomy" i.e. user-created tags that are not part of the core system
  • EAV (Entity-Attribute-Value)
    • the typical approach is for each question to be a column in the encounter table. As you start asking more questions, you need to add many many more columns. (This looks like a spreadsheet.)
    • EAV means you "turn this sideways" so instead of having one encounter with 50 columns, you would store one encounter and 50 observations.
    • Concepts represent the "questions" that would have been the many columns in a non-EAV encounter table
  • Observations
    • The core data in OpenMRS (as opposed to metadata)
    • concept_id -> the 'question' for this observation
    • value_xyz -> one of the value_xyz columns is filled in as the 'answer' for this observation
    • accession number -> used to link an observation back to a lab order that it originated from
    • value_group_id -> links multiple values for the same question
      • example 1: Chest Xray shows pneumonia AND infiltrate; as opposed to two chest xrays, one showing pneumonia, and another showing infiltrate
      • example 2: "Left" + "Upper Lobe" + "Pneumonia"
    • obs_group_id -> links multiple related observations that are all part of the same higher-level data point (e.g. Allergy cause, Allergy reaction, Allergy date)
  • Drugs
    • Why not just make these concepts? So we can representing both "Isoniazid" (a concept representing the generic drug) and "Isoniazid 300mg tablets" (an entry in the drug table)
  • UUIDs
    • Universally Unique IDs
    • You can create one of these anywhere, and you "always" (99.999...%) get a unique one
  • Concepts
    • Because of concepts we do not need to change the data model when we start asking new questions. We just add a row to the concept table
    • ... has a datatype
      • for questions, this specifies the datatype of the answer
      • datatype=N/A means this concept is only an answer, not a question
    • ... can be put in sets
    • ... can be complex (i.e. datatype is not just a primitive String or Number, but rather something like a video or an xml document)
      • complex concepts have "handlers" which know how to store and display things (e.g. a video of an echo loop is stored in some database)
      • image and text handlers are built into the core system
    • multi-valued datatypes can be represented as an obs group (commonly done for allergies) or you can use complex concepts to store this as xml
    • 'derived concepts' -> represents a calculation which lets you derive a value from other data (but you don't store data for a derived concept directy)
      • Example: "Pregnant?" -> diagnosis of pregnancy, or positive urine pregnancy test, or ...
      • Example: allows a report that has a "Pregnant?" question to be used against either obs for a boolean "is patient pregnant" or a datetime "expected delivery date"
  • Orders
    • Currently it's very simplistic in the data model
    • PIH is using the drug_order table now
    • Upcoming changes (not yet scheduled): much more sophisticated implementation of drug orders, lab orders, etc.
      • Regenstrief if building this on a data model derived from OpenMRS. We will copy a lot of what they do.
  • How do things get on the road map (e.g. why is order entry being built, but not billing)
    • "The community can drive whatever they want"
    • "If there's a portion of the data model that needs work from your perspective, then propose it"
    • Actually order entry is being worked on by Regenstrief for their own needs, and we're trying to leverage that work as much as possible
  • Upcoming changes to the data model that we know about:
    • In 1.7
      • Problem lists
      • Allergies
      • Location Hierarchy
      • Changes to Concept Name Tags
      • Boolean changes from 0/1 -> coded
    • In 1.9
      • Multiple providers per encounter
      • Visits
      • Addition attributes for Concept Mapping
    • Program Locations (when Jembi code is merged)
    • Orders (will change significantly if Regenstrief does a good job of implementing this)
  • How do you add a new address layout
    • You have to write xml, and put it openmrs-servlet.xml
    • We can probably commit your proposal to OpenMRS core
    • The columns in person_address can be renamed in the UI
  • Problem Lists
    • Can we support "continuing problems" (i.e. they have Fever, but this it's continued from before)
  • Allergies
    • Do these connect to the drug_ingredient table? Not yet. You can store allergies, but they don't do anything yet.
  • Can we support marking people as test patients? Would be nice--not quite sure how to do it?