diff --git a/export_db.sh b/export_db.sh index 2c5eff0..9c561cd 100755 --- a/export_db.sh +++ b/export_db.sh @@ -1,4 +1,4 @@ #!/bin/bash rm html/database.db -sqlite3 database.db '.dump pbs_item pbs_item_restriction pbs_restriction pbs_restriction_criteria pbs_criteria pbs_criteria_parameter' | sqlite3 html/database.db +sqlite3 database.db '.dump pbs_item pbs_mp pbs_mpp pbs_item_restriction pbs_restriction pbs_restriction_criteria pbs_criteria pbs_criteria_parameter' | sqlite3 html/database.db diff --git a/html/index.html b/html/index.html index ab25ed4..a2e4109 100644 --- a/html/index.html +++ b/html/index.html @@ -76,7 +76,7 @@ db = new SQL.Database(new Uint8Array(buf)); // Initialise search bar - const labels = execAsScalars(db.prepare('SELECT DISTINCT mp_preferred_term FROM pbs_item ORDER BY LOWER(mp_preferred_term)')); + const labels = execAsScalars(db.prepare('SELECT DISTINCT preferred_term FROM pbs_mp ORDER BY LOWER(preferred_term)')); const data = labels.map(label => ({'label': label})); const autocomplete = new Autocomplete(document.getElementById('search-input'), { data: data, @@ -88,7 +88,7 @@ function onClickSearchItem(item) { // Find matching PBS items - let stmt = db.prepare('SELECT * FROM pbs_item WHERE LOWER(mp_preferred_term) = ?'); + let stmt = db.prepare('SELECT * FROM pbs_item LEFT JOIN (SELECT code AS mpp_code, preferred_term AS mpp_preferred_term, mp_code FROM pbs_mpp) AS pbs_mpp ON pbs_item.mpp_code = pbs_mpp.mpp_code LEFT JOIN (SELECT code AS mp_code, preferred_term AS mp_preferred_term FROM pbs_mp) AS pbs_mp ON pbs_mpp.mp_code = pbs_mp.mp_code WHERE LOWER(mp_preferred_term) = ?'); stmt.bind([item.label.toLowerCase()]); const items = execAsObjects(stmt); diff --git a/import_pbs_xml.py b/import_pbs_xml.py index 94d75c6..d3b97bd 100644 --- a/import_pbs_xml.py +++ b/import_pbs_xml.py @@ -23,7 +23,13 @@ cur = con.cursor() # Init schema cur.execute('DROP TABLE IF EXISTS pbs_item') -cur.execute('CREATE TABLE pbs_item (code TEXT PRIMARY KEY, mpp_preferred_term TEXT, mp_preferred_term TEXT, maximum_prescribable_units INTEGER, number_repeats INTEGER, benefit_type TEXT)') +cur.execute('CREATE TABLE pbs_item (code TEXT PRIMARY KEY, mpp_code TEXT, maximum_prescribable_units INTEGER, number_repeats INTEGER, benefit_type TEXT)') + +cur.execute('DROP TABLE IF EXISTS pbs_mpp') +cur.execute('CREATE TABLE pbs_mpp (code TEXT PRIMARY KEY, mp_code TEXT, preferred_term TEXT)') + +cur.execute('DROP TABLE IF EXISTS pbs_mp') +cur.execute('CREATE TABLE pbs_mp (code TEXT PRIMARY KEY, preferred_term TEXT)') cur.execute('DROP TABLE IF EXISTS pbs_item_restriction') cur.execute('CREATE TABLE pbs_item_restriction (item_code TEXT, restriction_code INTEGER)') @@ -53,6 +59,8 @@ ns = {'pbs': 'http://schema.pbs.gov.au/', 'xlink': 'http://www.w3.org/1999/xlink # Get General Schedule program = next(p for p in root.find('pbs:schedule', ns).findall('pbs:program', ns) if p.find('pbs:info', ns).find('pbs:code', ns).text == 'GE') +mpps_to_parse = set() +mps_to_parse = set() restrictions_to_parse = set() criteria_to_parse = set() @@ -70,12 +78,7 @@ for item in program.findall('pbs:prescribing-rule', ns): benefit = benefits[0] mpp_id = item.find('pbs:ready-prepared', ns).find('pbs:mpp-reference', ns).get('{http://www.w3.org/1999/xlink}href').lstrip('#') - mpp = root.find('pbs:drugs-list', ns).find('pbs:mpp[@xml:id="' + mpp_id + '"]', ns) - mpp_preferred_term = mpp.find('pbs:preferred-term', ns).text - - mp_id = mpp.find('pbs:drug-references-list', ns).find('pbs:mp-reference', ns).get('{http://www.w3.org/1999/xlink}href').lstrip('#') - mp = root.find('pbs:drugs-list', ns).find('pbs:mp[@xml:id="' + mp_id + '"]', ns) - mp_preferred_term = mp.find('pbs:preferred-term[@rdf:resource="http://pbs.gov.au/clinical"]', ns).text + mpp_code = item.find('pbs:ready-prepared', ns).find('pbs:mpp-reference', ns).find('pbs:code', ns).text max_units = item.find('pbs:ready-prepared', ns).find('pbs:maximum-prescribable[@rdf:resource="http://pbs.gov.au/reference/unit-of-use"]', ns).find('pbs:value', ns).text max_repeats = item.find('pbs:ready-prepared', ns).find('pbs:number-repeats', ns).find('pbs:value', ns).text @@ -87,7 +90,7 @@ for item in program.findall('pbs:prescribing-rule', ns): 'http://pbs.gov.au/benefit-type/authority-required': 'authority', }[benefit.get('{http://www.w3.org/1999/02/22-rdf-syntax-ns#}resource')] - cur.execute('INSERT INTO pbs_item (code, mpp_preferred_term, mp_preferred_term, maximum_prescribable_units, number_repeats, benefit_type) VALUES (?, ?, ?, ?, ?, ?)', (code, mpp_preferred_term, mp_preferred_term, max_units, max_repeats, benefit_type)) + cur.execute('INSERT INTO pbs_item (code, mpp_code, maximum_prescribable_units, number_repeats, benefit_type) VALUES (?, ?, ?, ?, ?)', (code, mpp_code, max_units, max_repeats, benefit_type)) # Get restrictions if restrictions := benefit.find('pbs:restriction-references-list', ns): @@ -98,6 +101,39 @@ for item in program.findall('pbs:prescribing-rule', ns): # Queue this restriction for parsing restrictions_to_parse.add(restriction_id) + + # Queue the MPP for parsing + mpps_to_parse.add(mpp_id) + +# Parse MPPs +for mpp_id in sorted(list(mpps_to_parse)): + mpp = root.find('pbs:drugs-list', ns).find('pbs:mpp[@xml:id="' + mpp_id + '"]', ns) + mpp_code = mpp.find('pbs:code', ns).text + mpp_preferred_term = mpp.find('pbs:preferred-term', ns).text + + mp_id = mpp.find('pbs:drug-references-list', ns).find('pbs:mp-reference', ns).get('{http://www.w3.org/1999/xlink}href').lstrip('#') + mp = root.find('pbs:drugs-list', ns).find('pbs:mp[@xml:id="' + mp_id + '"]', ns) + mp_code = mp.find('pbs:code[@rdf:resource="http://pbs.gov.au/Drug/MP"]', ns).text # Must look this up because the in is only SNOMED + + cur.execute('INSERT INTO pbs_mpp (code, mp_code, preferred_term) VALUES (?, ?, ?)', (mpp_code, mp_code, mpp_preferred_term)) + + # Queue the MP for parsing + mps_to_parse.add(mp_id) + + # Get TPPs + for tpp_reference in mpp.find('pbs:drug-references-list', ns).findall('pbs:tpp-reference', ns): + tpp_id = tpp_reference.get('{http://www.w3.org/1999/xlink}href').lstrip('#') + + # Queue the TPP for parsing + tpps_to_parse.add((tpp_id, mpp_code)) + +# Parse MPs +for mp_id in sorted(list(mps_to_parse)): + mp = root.find('pbs:drugs-list', ns).find('pbs:mp[@xml:id="' + mp_id + '"]', ns) + mp_code = mp.find('pbs:code[@rdf:resource="http://pbs.gov.au/Drug/MP"]', ns).text # Also there are SNOMED codes but they are inconsistent + mp_preferred_term = mp.find('pbs:preferred-term[@rdf:resource="http://pbs.gov.au/clinical"]', ns).text + + cur.execute('INSERT INTO pbs_mp (code, preferred_term) VALUES (?, ?)', (mp_code, mp_preferred_term)) # Parse restrictions for restriction_id in sorted(list(restrictions_to_parse)):