Dumped on 2015-04-16
A textual description of the content such as a result summary. Several of these may belong to one document object.
F-Key | Name | Type | Description |
---|---|---|---|
pk_audit | integer | NOT NULL DEFAULT nextval('audit.audit_fields_pk_audit_seq'::regclass) | |
row_version | integer | NOT NULL | |
modified_when | timestamp with time zone | NOT NULL DEFAULT now() | |
modified_by | name | NOT NULL DEFAULT "current_user"() | |
pk | serial | PRIMARY KEY | |
doc_med.pk | fk_doc | integer | UNIQUE#1 |
text | text | UNIQUE#1 |
a medical document object possibly containing several data objects such as several pages of a paper document
F-Key | Name | Type | Description |
---|---|---|---|
pk_audit | integer | NOT NULL DEFAULT nextval('audit.audit_fields_pk_audit_seq'::regclass) | |
row_version | integer | NOT NULL | |
modified_when | timestamp with time zone | NOT NULL DEFAULT now() | |
modified_by | name | NOT NULL DEFAULT "current_user"() | |
pk | serial | PRIMARY KEY | |
fk_encounter | integer |
NOT NULL
the encounter in which this document was entered into the system |
|
fk_episode | integer |
NOT NULL
the episode this document pertains to, this may not be the only one applicable to the document (think discharge letters), see also lnk_doc_med2episode |
|
doc_type.pk | fk_type | integer |
NOT NULL
semantic type of document (not type of file or mime type), such as "referral letter", "discharge summary", etc. |
comment | text |
additional short comment such as "abdominal", "ward 3, Dr. Stein", etc. |
|
clin_when | timestamp with time zone |
NOT NULL
DEFAULT now()
date of document content creation (such as exam date), NOT date of document creation or date of import; may be imprecise such as "7/99" |
|
ext_ref | text |
external reference string of physical document, original paper copy can be found with this |
Tables referencing this one via Foreign Key Constraints:
possibly several of these form a medical document such as multiple scanned pages/images
F-Key | Name | Type | Description |
---|---|---|---|
pk | serial | PRIMARY KEY | |
doc_med.pk | fk_doc | integer | NOT NULL |
seq_idx | integer |
index of this object in the sequence of objects for this document |
|
comment | text |
optional tiny comment for this object, such as "page 1" |
|
fk_intended_reviewer | integer |
NOT NULL
who is *supposed* to review this item |
|
data | bytea |
NOT NULL
actual binary object data; here is why we use bytea: == -------------------------------------------------- To: leon@oss.minimetria.com Cc: pgsql-sql@postgresql.org Subject: Re: [SQL] Recommendation on bytea or blob for binary data like images Date: Fri, 02 Sep 2005 16:33:09 -0400 Message-ID: <17794.1125693189@sss.pgh.pa.us> From: Tom Lane <tgl@sss.pgh.pa.us> List-Archive: <http://archives.postgresql.org/pgsql-sql> List-Help: <mailto:majordomo@postgresql.org?body=help> List-ID: <pgsql-sql.postgresql.org> leon@oss.minimetria.com writes: > Hi, I"d like to know what the official recommendation is on which binary > datatype to use for common small-binary size use. If bytea will work for you, it"s definitely the thing to use. The only real drawback to bytea is that there"s currently no API to read and write bytea values in a streaming fashion. If your objects are small enough that you can load and store them as units, bytea is fine. BLOBs, on the other hand, have a number of drawbacks --- hard to dump, impossible to secure, etc. regards, tom lane == -------------------------------------------------- |
|
filename | text |
the filename from when the data was imported - if any, can be NULL, useful for re-export since legacy devices/applications might expect particular file names and not use mime types for file detection |
Name | Constraint |
---|---|
doc_obj_filename_check | CHECK ((btrim(COALESCE(filename, 'NULL'::text)) <> ''::text)) |
Tables referencing this one via Foreign Key Constraints:
this table enumerates the document types known to the system
F-Key | Name | Type | Description |
---|---|---|---|
pk | serial | PRIMARY KEY | |
name | text |
UNIQUE
NOT NULL
the name/label of the document type |
Tables referencing this one via Foreign Key Constraints:
links documents to any hospital stay they might pertain to
F-Key | Name | Type | Description |
---|---|---|---|
pk_audit | integer | NOT NULL DEFAULT nextval('audit.audit_fields_pk_audit_seq'::regclass) | |
row_version | integer | NOT NULL | |
modified_when | timestamp with time zone | NOT NULL DEFAULT now() | |
modified_by | name | NOT NULL DEFAULT "current_user"() | |
pk | serial | PRIMARY KEY | |
fk_stay | integer | NOT NULL | |
doc_med.pk | fk_document | integer | UNIQUE NOT NULL |
this allows linking documents to episodes, each document can apply to several episodes but only once each
F-Key | Name | Type | Description |
---|---|---|---|
pk_audit | integer | NOT NULL DEFAULT nextval('audit.audit_fields_pk_audit_seq'::regclass) | |
row_version | integer | NOT NULL | |
modified_when | timestamp with time zone | NOT NULL DEFAULT now() | |
modified_by | name | NOT NULL DEFAULT "current_user"() | |
pk | serial | PRIMARY KEY | |
fk_episode | integer | UNIQUE#1 NOT NULL | |
doc_med.pk | fk_doc_med | integer | UNIQUE#1 NOT NULL |
review table for documents (per object such as a page)
F-Key | Name | Type | Description |
---|---|---|---|
pk_audit | integer | NOT NULL DEFAULT nextval('audit.audit_fields_pk_audit_seq'::regclass) | |
row_version | integer | NOT NULL | |
modified_when | timestamp with time zone | NOT NULL DEFAULT now() | |
modified_by | name | NOT NULL DEFAULT "current_user"() | |
pk | integer | PRIMARY KEY DEFAULT nextval('clin.review_root_pk_seq'::regclass) | |
doc_obj.pk | fk_reviewed_row | integer | UNIQUE#1 NOT NULL |
fk_reviewer | integer | UNIQUE#1 NOT NULL | |
is_technically_abnormal | boolean | NOT NULL | |
clinically_relevant | boolean | NOT NULL | |
comment | text |
aggregates some document data descriptions
F-Key | Name | Type | Description |
---|---|---|---|
pk_patient | integer | ||
pk_doc | integer | ||
description | text | ||
pk_encounter | integer | ||
pk_episode | integer | ||
pk_health_issue | integer | ||
pk_doc_desc | integer |
SELECT vdm.pk_patient , dd.fk_doc AS pk_doc , dd.text AS description , vdm.pk_encounter , vdm.pk_episode , vdm.pk_health_issue , dd.pk AS pk_doc_desc FROM blobs.doc_desc dd , blobs.v_doc_med vdm WHERE (dd.fk_doc = vdm.pk_doc);
F-Key | Name | Type | Description |
---|---|---|---|
pk_patient | integer | ||
pk_doc | integer | ||
clin_when | timestamp with time zone | ||
type | text | ||
l10n_type | text | ||
ext_ref | text | ||
episode | text | ||
comment | text | ||
episode_open | boolean | ||
pk_type | integer | ||
pk_encounter | integer | ||
pk_episode | integer | ||
pk_health_issue | integer | ||
modified_when | timestamp with time zone | ||
modified_by | name | ||
xmin_doc_med | xid | ||
health_issue | text |
SELECT ( SELECT encounter.fk_patient FROM clin.encounter WHERE (encounter.pk = dm.fk_encounter) ) AS pk_patient , dm.pk AS pk_doc , dm.clin_when , dt.name AS type , _ (dt.name) AS l10n_type , dm.ext_ref , cle.description AS episode , dm.comment , cle.is_open AS episode_open , dm.fk_type AS pk_type , dm.fk_encounter AS pk_encounter , dm.fk_episode AS pk_episode , cle.fk_health_issue AS pk_health_issue , dm.modified_when , dm.modified_by , dm.xmin AS xmin_doc_med , chi.description AS health_issue FROM blobs.doc_med dm , blobs.doc_type dt , (clin.episode cle LEFT JOIN clin.health_issue chi ON ( (chi.pk = cle.fk_health_issue) ) ) WHERE ( (dt.pk = dm.fk_type) AND (cle.pk = dm.fk_episode) );
F-Key | Name | Type | Description |
---|---|---|---|
pk_patient | integer | ||
modified_when | timestamp with time zone | ||
clin_when | timestamp with time zone | ||
modified_by | text | ||
soap_cat | text | ||
narrative | text | ||
pk_encounter | integer | ||
pk_episode | integer | ||
pk_health_issue | integer | ||
src_pk | integer | ||
src_table | text |
SELECT ( SELECT encounter.fk_patient FROM clin.encounter WHERE (encounter.pk = dm.fk_encounter) ) AS pk_patient , dm.modified_when , dm.clin_when , COALESCE ( ( SELECT staff.short_alias FROM dem.staff WHERE (staff.db_user = dm.modified_by) ) , ( ('<'::text || (dm.modified_by)::text ) || '>'::text ) ) AS modified_by , NULL::text AS soap_cat , ( ( ( ( ( (_ ('Document'::text) || ': '::text ) || _ (dt.name) ) || COALESCE ( ( (' "'::text || dm.ext_ref) || '" ('::text) , ' ('::text) ) || to_char (dm.clin_when ,'YYYY-MM-DD HH24:MI'::text ) ) || ')'::text ) || COALESCE ( (' '::text || dm.comment) ,''::text ) ) AS narrative , dm.fk_encounter AS pk_encounter , dm.fk_episode AS pk_episode , ( SELECT episode.fk_health_issue FROM clin.episode WHERE (episode.pk = dm.fk_episode) ) AS pk_health_issue , dm.pk AS src_pk ,'blobs.doc_med'::text AS src_table FROM blobs.doc_med dm , blobs.doc_type dt WHERE (dt.pk = dm.fk_type);
list active document types, those that are activated for use
F-Key | Name | Type | Description |
---|---|---|---|
pk_doc_type | integer | ||
type | text | ||
l10n_type | text | ||
is_user_defined | boolean | ||
is_in_use | boolean | ||
xmin_doc_type | xid |
SELECT dt.pk AS pk_doc_type , dt.name AS type , _ (dt.name) AS l10n_type , (NOT (EXISTS ( SELECT 1 FROM ref.document_type WHERE (document_type.description = dt.name) ) ) ) AS is_user_defined , (EXISTS ( SELECT 1 FROM blobs.doc_med WHERE (doc_med.fk_type = dt.pk) ) ) AS is_in_use , dt.xmin AS xmin_doc_type FROM blobs.doc_type dt;
shows the latest picture of the patient, currently the highest seq_idx of the newest document of type "patient photograph"
F-Key | Name | Type | Description |
---|---|---|---|
pk_patient | integer | ||
doc_comment | text | ||
date_taken | timestamp with time zone | ||
ext_ref | text | ||
obj_seq_idx | integer | ||
obj_comment | text | ||
pk_doc | integer | ||
pk_obj | integer | ||
image | bytea |
SELECT vo4d.pk_patient , vo4d.doc_comment , vo4d.date_generated AS date_taken , vo4d.ext_ref , vo4d.seq_idx AS obj_seq_idx , vo4d.obj_comment , vo4d.pk_doc , vo4d.pk_obj , bdo.data AS image FROM blobs.v_obj4doc_no_data vo4d , blobs.doc_obj bdo WHERE ( ( (vo4d.type = 'patient photograph'::text) AND (vo4d.seq_idx = ( SELECT max (vo4d1.seq_idx) AS max FROM blobs.v_obj4doc_no_data vo4d1 WHERE ( (vo4d1.pk_patient = vo4d.pk_patient) AND (vo4d1.type = 'patient photograph'::text) ) GROUP BY vo4d1.date_generated ORDER BY vo4d1.date_generated DESC LIMIT 1 ) ) ) AND (bdo.pk = vo4d.pk_obj) );
denormalized metadata for blobs.doc_obj but without the data itself
F-Key | Name | Type | Description |
---|---|---|---|
pk_patient | integer | ||
pk_obj | integer | ||
seq_idx | integer | ||
size | integer | ||
date_generated | timestamp with time zone | ||
type | text | ||
l10n_type | text | ||
ext_ref | text | ||
episode | text | ||
doc_comment | text | ||
obj_comment | text | ||
filename | text | ||
pk_intended_reviewer | integer | ||
reviewed | boolean | ||
reviewed_by_you | boolean | ||
reviewed_by_intended_reviewer | boolean | ||
pk_doc | integer | ||
pk_type | integer | ||
pk_encounter | integer | ||
pk_episode | integer | ||
pk_health_issue | integer | ||
xmin_doc_obj | xid |
SELECT vdm.pk_patient , dobj.pk AS pk_obj , dobj.seq_idx , octet_length (COALESCE (dobj.data ,'\x'::bytea ) ) AS size , vdm.clin_when AS date_generated , vdm.type , vdm.l10n_type , vdm.ext_ref , vdm.episode , vdm.comment AS doc_comment , dobj.comment AS obj_comment , dobj.filename , dobj.fk_intended_reviewer AS pk_intended_reviewer , (EXISTS ( SELECT 1 FROM blobs.reviewed_doc_objs WHERE (reviewed_doc_objs.fk_reviewed_row = dobj.pk) ) ) AS reviewed , (EXISTS ( SELECT 1 FROM blobs.reviewed_doc_objs WHERE ( (reviewed_doc_objs.fk_reviewed_row = dobj.pk) AND (reviewed_doc_objs.fk_reviewer = ( SELECT staff.pk FROM dem.staff WHERE (staff.db_user = "current_user" () ) ) ) ) ) ) AS reviewed_by_you , (EXISTS ( SELECT 1 FROM blobs.reviewed_doc_objs WHERE ( (reviewed_doc_objs.fk_reviewed_row = dobj.pk) AND (reviewed_doc_objs.fk_reviewer = dobj.fk_intended_reviewer) ) ) ) AS reviewed_by_intended_reviewer , vdm.pk_doc , vdm.pk_type , vdm.pk_encounter , vdm.pk_episode , vdm.pk_health_issue , dobj.xmin AS xmin_doc_obj FROM blobs.v_doc_med vdm , blobs.doc_obj dobj WHERE (vdm.pk_doc = dobj.fk_doc);
F-Key | Name | Type | Description |
---|---|---|---|
pk_doc_obj | integer | ||
reviewer | text | ||
is_technically_abnormal | boolean | ||
clinically_relevant | boolean | ||
is_review_by_responsible_reviewer | boolean | ||
is_your_review | boolean | ||
comment | text | ||
reviewed_when | timestamp with time zone | ||
modified_by | name | ||
pk_review_root | integer | ||
pk_reviewer | integer | ||
pk_patient | integer | ||
pk_encounter | integer | ||
pk_episode | integer | ||
pk_health_issue | integer |
SELECT rdo.fk_reviewed_row AS pk_doc_obj , COALESCE ( ( SELECT staff.short_alias FROM dem.staff WHERE (staff.pk = rdo.fk_reviewer) ) , ( ('<#'::text || rdo.fk_reviewer) || '>'::text ) ) AS reviewer , rdo.is_technically_abnormal , rdo.clinically_relevant , (EXISTS ( SELECT 1 FROM blobs.doc_obj WHERE ( (doc_obj.pk = rdo.fk_reviewed_row) AND (doc_obj.fk_intended_reviewer = rdo.fk_reviewer) ) ) ) AS is_review_by_responsible_reviewer , (EXISTS ( SELECT 1 FROM dem.staff WHERE ( (staff.pk = rdo.fk_reviewer) AND (staff.db_user = "current_user" () ) ) ) ) AS is_your_review , rdo.comment , rdo.modified_when AS reviewed_when , rdo.modified_by , rdo.pk AS pk_review_root , rdo.fk_reviewer AS pk_reviewer , ( SELECT v_obj4doc_no_data.pk_patient FROM blobs.v_obj4doc_no_data WHERE (v_obj4doc_no_data.pk_obj = rdo.fk_reviewed_row) ) AS pk_patient , ( SELECT v_obj4doc_no_data.pk_encounter FROM blobs.v_obj4doc_no_data WHERE (v_obj4doc_no_data.pk_obj = rdo.fk_reviewed_row) ) AS pk_encounter , ( SELECT v_obj4doc_no_data.pk_episode FROM blobs.v_obj4doc_no_data WHERE (v_obj4doc_no_data.pk_obj = rdo.fk_reviewed_row) ) AS pk_episode , ( SELECT v_obj4doc_no_data.pk_health_issue FROM blobs.v_obj4doc_no_data WHERE (v_obj4doc_no_data.pk_obj = rdo.fk_reviewed_row) ) AS pk_health_issue FROM blobs.reviewed_doc_objs rdo;
DECLARE _pk_doc alias for $1; _pk_encounter alias for $2; _del_note text; _doc_row record; _obj_row record; tmp text; BEGIN select * into _doc_row from blobs.doc_med where pk = _pk_doc; _del_note := _('Deletion of document') || E': ' || ' ' || to_char(_doc_row.clin_when, 'YYYY-MM-DD HH24:MI') || ' "' || (select _(dt.name) from blobs.doc_type dt where pk = _doc_row.fk_type) || '"' || coalesce(' (' || _doc_row.ext_ref || ')', '') || coalesce(E' ' || _doc_row.comment, '') ; FOR _obj_row IN select * from blobs.doc_obj where fk_doc = _pk_doc order by seq_idx LOOP _del_note := _del_note || E' ' || ' #' || coalesce(_obj_row.seq_idx, '-1') || ': "' || coalesce(_obj_row.comment, '') || E'" ' || ' ' || coalesce(_obj_row.filename, '') || E' '; end LOOP; insert into clin.clin_narrative (fk_encounter, fk_episode, narrative, soap_cat) values ( _pk_encounter, _doc_row.fk_episode, _del_note, NULL ); -- should auto-cascade: --delete from blobs.doc_obj where fk_doc = _pk_doc; -- should auto-NULL: --bill.bill.fk_doc delete from blobs.doc_med where pk = _pk_doc; return True; END;
DECLARE _pk_doc_part alias for $1; _pk_encounter alias for $2; _del_note text; _doc_row record; _obj_row record; tmp text; BEGIN select * into _obj_row from blobs.doc_obj where pk = _pk_doc_part; select * into _doc_row from blobs.doc_med where pk = _obj_row.fk_doc; _del_note := _('Deletion of part from document') || E': ' || ' ' || to_char(_doc_row.clin_when, 'YYYY-MM-DD HH24:MI') || ' "' || (select _(dt.name) from blobs.doc_type dt where pk = _doc_row.fk_type) || '"' || coalesce(' (' || _doc_row.ext_ref || ')', '') || coalesce(E' ' || _doc_row.comment, '') || E' ' || ' #' || coalesce(_obj_row.seq_idx, '-1') || ': "' || coalesce(_obj_row.comment, '') || E'" ' || ' ' || coalesce(_obj_row.filename, '') || E' ' ; insert into clin.clin_narrative (fk_encounter, fk_episode, narrative, soap_cat) values ( _pk_encounter, _doc_row.fk_episode, _del_note, NULL ); delete from blobs.doc_obj where pk = _pk_doc_part; return True; END;
This trigger function is called before a lnk_doc_med2episode row is inserted or updated. It makes sure the episode does not duplicate the primary episode for this document listed in doc_med. If it does the insert/update is skipped.
BEGIN -- if already in doc_med perform 1 from blobs.doc_med dm where dm.fk_episode = NEW.fk_episode and dm.pk = NEW.fk_doc_med; if FOUND then -- skip the insert/update return null; end if; return NEW; END;
BEGIN if (NEW.data != OLD.data) or ((NEW.data != OLD.data) is NULL) then delete from blobs.reviewed_doc_objs where fk_reviewed_row = OLD.pk; end if; return NEW; END;
This trigger function is called when a doc_med row is inserted or updated. It makes sure the primary episode listed in doc_med is not duplicated in lnk_doc_med2episode for the same document. If it exists in the latter it is removed from there.
BEGIN -- if update if TG_OP = 'UPDATE' then -- and no change if NEW.fk_episode = OLD.fk_episode then -- then do nothing return NEW; end if; end if; -- if already in link table perform 1 from blobs.lnk_doc_med2episode ldm2e where ldm2e.fk_episode = NEW.fk_episode and ldm2e.fk_doc_med = NEW.pk; if FOUND then -- delete from link table delete from blobs.lnk_doc_med2episode where fk_episode = NEW.fk_episode and fk_doc_med = NEW.pk; end if; return NEW; END;
Set the default on blobs.doc_obj.fk_intended_reviewer.
DECLARE _pk_patient integer; _pk_provider integer; BEGIN -- explicitely set ? if NEW.fk_intended_reviewer is not NULL then return NEW; end if; -- find patient via document select fk_patient into _pk_patient from clin.encounter where clin.encounter.pk = ( select fk_encounter from blobs.doc_med where pk = NEW.fk_doc ); -- does patient have primary provider ? select fk_primary_provider into _pk_provider from dem.identity where dem.identity.pk = _pk_patient; if _pk_provider is not NULL then NEW.fk_intended_reviewer := _pk_provider; return NEW; end if; -- else use CURRENT_USER select pk into _pk_provider from dem.staff where dem.staff.db_user = current_user; NEW.fk_intended_reviewer := _pk_provider; return NEW; END;
declare msg text; begin if NEW.seq_idx is NULL then return NEW; end if; perform 1 from blobs.doc_obj where pk <> NEW.pk and fk_doc = NEW.fk_doc and seq_idx = NEW.seq_idx; if FOUND then msg := '[blobs.trf_verify_page_number]: uniqueness violation: seq_idx [' || NEW.seq_idx || '] already exists for fk_doc [' || NEW.fk_doc || ']'; raise exception '%', msg; end if; return NEW; end;
Generated by PostgreSQL Autodoc