Data Dictionary for OpenEMR

sunsetsystems wrote on Tuesday, April 01, 2014:

I’ve been discussing with a client their need to make some improvements to Layout Based Forms. One of these is a requirement to “share data among multiple forms”. That is, you might have two different encounter forms that can insert or update the same data item. Furthermore this data item might be something like DOB that is already stored somewhere else in the system.

A related thought is that some things that are put into encounter forms are more properly attributes of the visit itself, and are not of some repeatable measurement or procedure. It would be nice to have user-definable visit attributes.

So this brings us to the concept of defining data items and their values separately from layout items. Thus a “data dictionary”.

Here’s a sample table layout that I came up with to support this:

CREATE TABLE `data_dictionary` (
  `category_id`  varchar(31)  NOT NULL DEFAULT '' COMMENT 'Patient, Encounter or a forms.formdir value',
  `attribute_id` varchar(31)  NOT NULL DEFAULT '' COMMENT 'Identifies the data item within category',
  `component_id` int(11)      NOT NULL DEFAULT 0  COMMENT 'Usually 0, increments for compound data types',
  `data_type`    varchar(31)  NOT NULL DEFAULT '' COMMENT 'text, longtext, list value, addrbook item, date, datetime, pharmacy, squad, user, billing code, issue, facility',
  `list_id`      varchar(31)  NOT NULL DEFAULT '' COMMENT 'Identifies the list if this is list based',
  `max_length`   int(11)      NOT NULL default 0  COMMENT 'Maximum length of a value',
  `options`      varchar(31)  NOT NULL DEFAULT '' COMMENT 'In case other qualifiers are needed',
  `description`  varchar(255) NOT NULL DEFAULT '' COMMENT 'Describes what this is for',
  -- In the case of a compound data type the following are ignored for all but the first component. --
  `multiple`     tinyint(1)   NOT NULL DEFAULT 0  COMMENT '1 if multiple values/selections are allowed',
  `status`       tinyint(1)   NOT NULL DEFAULT 0  COMMENT '0=system, 1=user, 2=deactivated',
  PRIMARY KEY (`category_id`, `attribute_id`, `component_id`)
);

Note that a data item is keyed on a category_id, attribute_id and component_id.

category_id indicates if it’s a patient attribute, encounter attribute or form attribute, and if a form attribute which form. We’ll probably want additional categories.

attribute_id is the name of the data item within its category. An attribute_id that is already a column name in its respective table will have its values stored in that column; otherwise they will be stored in a separate “vertical” table of attribute values similarly to the way the lbf_data table does it. This supports creation of user-defined attributes and has other potential benefits that we can get into later.

component_id exists to support compound data items – items with multiple components, defined with multiple data_dictionary rows, each having the same category_id and attribute_id. For simple data items component_id would always be 0. An example of a compound data item would be the “exam results” data type currently defined for layout based forms.

I can write more, but don’t want to dive into it too deep before getting some initial feedback. Please feel free to comment. Thanks!

Rod
http://www.sunsetsystems.com/

tmccormi wrote on Wednesday, April 02, 2014:

I’m not sure using a table in the database is the right model,
Perhaps an include library with JSON schema formatted data? http://json-schema.org/

IF you did that, then some future form rendering tools could be used, such as http://www.alpacajs.org/

–Tony

mdsupport wrote on Wednesday, April 02, 2014:

It may be good to allow display of information but letting LBFs update information in other tables should not be done through a linear structure like this. form.formdir elements involve logic that raw data approach will ignore and create havoc. Also consider the ACL implications. In ideal world all updates need to be done through classes so logic is central regardless of the presentations.

sunsetsystems wrote on Thursday, April 03, 2014:

I think what this boils down to is the concept is just too complicated for OpenEMR. We’re going to look at a simpler approach.

I do agree that the data model should be based on PHP classes, though that in itself does not preclude a data dictionary concept.

Thanks for the feedback.

Rod
http://www.sunsetsystems.com/

mdsupport wrote on Thursday, April 03, 2014:

Couple of suggestions based on stuff we have implemented -

  1. Plug-in approach works for complicated stuff. One can even think about converting data types to plug-in with project providing a library of plug-ins and users add custom logic modules without needing any modifications.
  2. Add patient data and encounter data as data types which look at object.field as source. The only restriction we have in place is those fields automatically become display. We enforce that by offering only MySQL views which do the selection logic. But you can offer all tables and all fields as well.

BTW - if you are touching forms manager, it would be good to make sure columns in standard tables are never deleted.

bradymiller wrote on Friday, April 04, 2014:

Rod,
Let us know what the simpler aproach is. My stance always leans towards the solution of the one doing the work.
-brady
OpenEMR