Module Gnumed.business.gmCoding

GNUmed coding systems handling middleware

Expand source code
"""GNUmed coding systems handling middleware"""
#============================================================
__license__ = "GPL"
__author__ = "K.Hilbert <Karsten.Hilbert@gmx.net>"


# stdlib
import sys
import logging


# GNUmed modules
if __name__ == '__main__':
        sys.path.insert(0, '../../')
from Gnumed.pycommon import gmPG2
from Gnumed.pycommon import gmBusinessDBObject
from Gnumed.pycommon import gmHooks
from Gnumed.pycommon import gmDispatcher


_log = logging.getLogger('gm.coding')

#============================================================
def _on_code_link_modified():
        """Always relates to the active patient."""
        gmHooks.run_hook_script(hook = 'after_code_link_modified')

gmDispatcher.connect(_on_code_link_modified, 'clin.episode_code_mod_db')
gmDispatcher.connect(_on_code_link_modified, 'clin.rfe_code_mod_db')
gmDispatcher.connect(_on_code_link_modified, 'clin.aoe_code_mod_db')
gmDispatcher.connect(_on_code_link_modified, 'clin.health_issue_code_mod_db')
gmDispatcher.connect(_on_code_link_modified, 'clin.narrative_code_mod_db')
gmDispatcher.connect(_on_code_link_modified, 'clin.procedure_code_mod_db')

#============================================================
# generic linked code handling
#------------------------------------------------------------
_SQL_get_generic_linked_codes = "SELECT * FROM clin.v_linked_codes WHERE %s"

class cGenericLinkedCode(gmBusinessDBObject.cBusinessDBObject):
        """Represents a generic linked code.

        READ ONLY
        """
        _cmd_fetch_payload = _SQL_get_generic_linked_codes % "pk_lnk_code2item = %s"
        _cmds_store_payload:list = []
        _updatable_fields:list = []
#------------------------------------------------------------
def get_generic_linked_codes(order_by=None):
        if order_by is None:
                order_by = 'true'
        else:
                order_by = 'true ORDER BY %s' % order_by

        cmd = _SQL_get_generic_linked_codes % order_by
        rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd}], get_col_idx = True)
        return [ cGenericLinkedCode(row = {'data': r, 'idx': idx, 'pk_field': 'pk_lnk_code2item'}) for r in rows ]
#============================================================
# this class represents a generic (non-qualified) code
#------------------------------------------------------------
_SQL_get_generic_code = "SELECT * FROM ref.v_generic_codes WHERE %s"

class cGenericCode(gmBusinessDBObject.cBusinessDBObject):
        """READ ONLY"""
        _cmd_fetch_payload = _SQL_get_generic_code % "pk_generic_code = %s"
        _cmds_store_payload:list = []
        _updatable_fields:list = []
#------------------------------------------------------------
def get_generic_codes(order_by=None):
        if order_by is None:
                order_by = 'true'
        else:
                order_by = 'true ORDER BY %s' % order_by

        cmd = _SQL_get_generic_code % order_by
        rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd}], get_col_idx = True)
        return [ cGenericCode(row = {'data': r, 'idx': idx, 'pk_field': 'pk_generic_code'}) for r in rows ]

#============================================================
# module level functions
#------------------------------------------------------------
def get_coded_terms(coding_systems=None, languages=None, order_by=None):

        where_snippets = []
        args = {}

        if coding_systems is not None:
                where_snippets.append("((coding_system = ANY(%(sys)s)) OR (coding_system_long = ANY(%(sys)s))")
                args['sys'] = coding_systems

        if languages is not None:
                where_snippets.append('lang = ANY(%(lang)s)')
                args['lang'] = languages

        cmd = 'select * from ref.v_coded_terms'

        if len(where_snippets) > 0:
                cmd += ' WHERE %s' % ' AND '.join(where_snippets)

        if order_by is not None:
                cmd += ' ORDER BY %s' % order_by

        rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': args}], get_col_idx = False)

        return rows

#============================================================
def get_data_sources(order_by='name_long, lang, version'):
        cmd = 'SELECT * FROM ref.data_source ORDER BY %s' % order_by
        rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd}], get_col_idx = False)
        return rows

#============================================================
def create_data_source(long_name=None, short_name=None, version=None, source=None, language=None):

                args = {
                        'lname': long_name,
                        'sname': short_name,
                        'ver': version,
                        'src': source,
                        'lang': language
                }

                cmd = "SELECT pk FROM ref.data_source WHERE name_long = %(lname)s AND name_short = %(sname)s AND version = %(ver)s"
                rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': args}])
                if len(rows) > 0:
                        return rows[0]['pk']

                cmd = """
                        INSERT INTO ref.data_source (name_long, name_short, version, source, lang)
                        VALUES (
                                %(lname)s,
                                %(sname)s,
                                %(ver)s,
                                %(src)s,
                                %(lang)s
                        )
                        RETURNING pk
                """
                rows, idx = gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': args}], return_data = True)

                return rows[0]['pk']

#============================================================
# main
#------------------------------------------------------------
if __name__ == "__main__":

        if len(sys.argv) < 2:
                sys.exit()

        if sys.argv[1] != 'test':
                sys.exit()

        #----------------------------------------------------
        def test_get_generic_codes():
                print("generic codes:")
                for code in get_generic_codes():
                        print(code)
        #----------------------------------------------------
        def test_get_coded_terms():
                print("known codes:")
                for term in get_coded_terms():
                        print(term)
        #----------------------------------------------------
        def test_get_generic_linked_codes():
                print("generically linked generic codes:")
                for code in get_generic_linked_codes():
                        print(code)
        #----------------------------------------------------
        #test_get_coded_terms()
        #test_get_generic_codes()
        test_get_generic_linked_codes()

#============================================================

Functions

def create_data_source(long_name=None, short_name=None, version=None, source=None, language=None)
Expand source code
def create_data_source(long_name=None, short_name=None, version=None, source=None, language=None):

                args = {
                        'lname': long_name,
                        'sname': short_name,
                        'ver': version,
                        'src': source,
                        'lang': language
                }

                cmd = "SELECT pk FROM ref.data_source WHERE name_long = %(lname)s AND name_short = %(sname)s AND version = %(ver)s"
                rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': args}])
                if len(rows) > 0:
                        return rows[0]['pk']

                cmd = """
                        INSERT INTO ref.data_source (name_long, name_short, version, source, lang)
                        VALUES (
                                %(lname)s,
                                %(sname)s,
                                %(ver)s,
                                %(src)s,
                                %(lang)s
                        )
                        RETURNING pk
                """
                rows, idx = gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': args}], return_data = True)

                return rows[0]['pk']
def get_coded_terms(coding_systems=None, languages=None, order_by=None)
Expand source code
def get_coded_terms(coding_systems=None, languages=None, order_by=None):

        where_snippets = []
        args = {}

        if coding_systems is not None:
                where_snippets.append("((coding_system = ANY(%(sys)s)) OR (coding_system_long = ANY(%(sys)s))")
                args['sys'] = coding_systems

        if languages is not None:
                where_snippets.append('lang = ANY(%(lang)s)')
                args['lang'] = languages

        cmd = 'select * from ref.v_coded_terms'

        if len(where_snippets) > 0:
                cmd += ' WHERE %s' % ' AND '.join(where_snippets)

        if order_by is not None:
                cmd += ' ORDER BY %s' % order_by

        rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': args}], get_col_idx = False)

        return rows
def get_data_sources(order_by='name_long, lang, version')
Expand source code
def get_data_sources(order_by='name_long, lang, version'):
        cmd = 'SELECT * FROM ref.data_source ORDER BY %s' % order_by
        rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd}], get_col_idx = False)
        return rows
def get_generic_codes(order_by=None)
Expand source code
def get_generic_codes(order_by=None):
        if order_by is None:
                order_by = 'true'
        else:
                order_by = 'true ORDER BY %s' % order_by

        cmd = _SQL_get_generic_code % order_by
        rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd}], get_col_idx = True)
        return [ cGenericCode(row = {'data': r, 'idx': idx, 'pk_field': 'pk_generic_code'}) for r in rows ]
def get_generic_linked_codes(order_by=None)
Expand source code
def get_generic_linked_codes(order_by=None):
        if order_by is None:
                order_by = 'true'
        else:
                order_by = 'true ORDER BY %s' % order_by

        cmd = _SQL_get_generic_linked_codes % order_by
        rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd}], get_col_idx = True)
        return [ cGenericLinkedCode(row = {'data': r, 'idx': idx, 'pk_field': 'pk_lnk_code2item'}) for r in rows ]

Classes

class cGenericCode (aPK_obj: int | dict = None, row: dict = None, link_obj=None)

READ ONLY

Call init from child classes like so:

    super().__init__(aPK_obj = aPK_obj, row = row, link_obj = link_obj)

Args

aPK_obj
retrieve data from backend
  • a simple value the primary key WHERE condition must be a simple column
  • a dictionary of values the primary key WHERE condition must be a subselect consuming the dict and producing the single-value primary key
row
must hold the fields
  • idx: a dict mapping field names to position
  • data: the field values in a list (as returned by cursor.fetchone() in the DB-API)
  • pk_field: the name of the primary key field OR
  • pk_obj: a dictionary suitable for passed to cursor.execute and holding the primary key values, used for composite PKs
  • for example:
    row = {
            'data': rows[0],
            'idx': idx,
            'pk_field': 'pk_XXX (the PK column name)',
            'pk_obj': {'pk_col1': pk_col1_val, 'pk_col2': pk_col2_val}
    }
    rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': args}], get_col_idx = True)
    objects = [ cChildClass(row = {'data': r, 'idx': idx, 'pk_field': 'the PK column name'}) for r in rows ]
    
Expand source code
class cGenericCode(gmBusinessDBObject.cBusinessDBObject):
        """READ ONLY"""
        _cmd_fetch_payload = _SQL_get_generic_code % "pk_generic_code = %s"
        _cmds_store_payload:list = []
        _updatable_fields:list = []

Ancestors

Inherited members

class cGenericLinkedCode (aPK_obj: int | dict = None, row: dict = None, link_obj=None)

Represents a generic linked code.

READ ONLY

Call init from child classes like so:

    super().__init__(aPK_obj = aPK_obj, row = row, link_obj = link_obj)

Args

aPK_obj
retrieve data from backend
  • a simple value the primary key WHERE condition must be a simple column
  • a dictionary of values the primary key WHERE condition must be a subselect consuming the dict and producing the single-value primary key
row
must hold the fields
  • idx: a dict mapping field names to position
  • data: the field values in a list (as returned by cursor.fetchone() in the DB-API)
  • pk_field: the name of the primary key field OR
  • pk_obj: a dictionary suitable for passed to cursor.execute and holding the primary key values, used for composite PKs
  • for example:
    row = {
            'data': rows[0],
            'idx': idx,
            'pk_field': 'pk_XXX (the PK column name)',
            'pk_obj': {'pk_col1': pk_col1_val, 'pk_col2': pk_col2_val}
    }
    rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': args}], get_col_idx = True)
    objects = [ cChildClass(row = {'data': r, 'idx': idx, 'pk_field': 'the PK column name'}) for r in rows ]
    
Expand source code
class cGenericLinkedCode(gmBusinessDBObject.cBusinessDBObject):
        """Represents a generic linked code.

        READ ONLY
        """
        _cmd_fetch_payload = _SQL_get_generic_linked_codes % "pk_lnk_code2item = %s"
        _cmds_store_payload:list = []
        _updatable_fields:list = []

Ancestors

Inherited members