diff --git a/cumulus_library/.sqlfluff b/cumulus_library/.sqlfluff index c3bfd9e6..99b557e0 100644 --- a/cumulus_library/.sqlfluff +++ b/cumulus_library/.sqlfluff @@ -170,6 +170,11 @@ schema = 'category': { 'coding': True, 'code': True, 'display': True, 'system': True, 'text': True }, + 'component': { + 'valueQuantity': { + 'code': True, 'comparator': True, 'system': True, 'unit': True, 'value': True + }, + }, 'status': True, 'code': { 'coding': True, 'code': True, 'display': True, 'system': True, 'text': True diff --git a/cumulus_library/__init__.py b/cumulus_library/__init__.py index e110c308..8c3bbf27 100644 --- a/cumulus_library/__init__.py +++ b/cumulus_library/__init__.py @@ -1,3 +1,3 @@ """Package metadata""" -__version__ = "2.0.1" +__version__ = "2.1.0" diff --git a/cumulus_library/databases.py b/cumulus_library/databases.py index b876d64a..e4ce973e 100644 --- a/cumulus_library/databases.py +++ b/cumulus_library/databases.py @@ -14,7 +14,7 @@ import os import sys from pathlib import Path -from typing import Protocol +from typing import Any, Protocol import cumulus_fhir_support import duckdb @@ -44,60 +44,78 @@ def fetchall(self) -> list[list] | None: class DatabaseParser(abc.ABC): """Parses information_schema results from a database""" - def _parse_found_schema( - self, expected: dict[dict[list]], schema: dict[list] - ) -> dict: - """Checks for presence of field for each column in a table + @abc.abstractmethod + def parse_found_schema(self, schema: dict[str, str]) -> dict: + """Parses a database-provided schema string. - :param expected: A nested dict describing the expected data format of - a table. Expected format is like this: + :param schema: the results of a query from the get_column_datatype method + of the template_sql.templates function. It looks like this (for athena at + least, but the values are opaque strings and database-provider-specific): { - "object_col":["member_a", "member_b"] - "primitive_col": [] + 'object_col': 'row(member_a varchar, member_b date)', + 'primitive_col': 'varchar', + } + + :returns: a dictionary with an entry for every field present in the schema. + For the above example, this should return: + { + 'object_col': { + 'member_a': {}, + 'member_b': {}, + }, + 'primitive_col': {}, } - :param schema: the results of a query from the get_column_datatype method - of the template_sql.templates function. It looks like this: - [ - ('object_col', 'row(member_a VARCHAR, member_b DATE)'), - ('primitive_col', 'VARCHAR') - ] - - The actual contents of schema are database dependent. This naive method - is a first pass, ignoring complexities of differing database variable - types, just iterating through looking for column names. - - TODO: on a per database instance, consider a more nuanced approach if needed - (compared to just checking if the schema contains the field name) """ + + def _recursively_validate( + self, expected: dict[str, Any], schema: dict[str, Any] + ) -> dict[str, Any]: + schema = schema or {} output = {} for column, fields in expected.items(): - column_lower = column.lower() - - # is this an object column? (like: "subject": ["reference"]) - if fields: - col_schema = schema.get(column_lower, "").lower() - output[column] = { - # TODO: make this check more robust - field: field.lower() in col_schema - for field in fields - } - - # otherwise this is a primitive col (like: "recordedDate": None) + col_schema = schema.get(column.lower()) + + # Is `fields` an falsy? (like: "recordedDate": None or [] or {}) + # This means we just want to check existance of `column` + # otherwise this is a primitive col + if not fields: + output[column] = col_schema is not None + + # Is `fields` a list? (like: "subject": ["reference"]) + # This means we should check existance of all mentioned children. + elif isinstance(fields, list): + for field in fields: + subschema = self._recursively_validate({field: None}, col_schema) + output.setdefault(column, {}).update(subschema) + + # Is `fields` a dict? + # Like: "component": {"valueQuantity": ["unit", "value"]} + # This means we should descend one level + elif isinstance(fields, dict): + subschema = self._recursively_validate(fields, col_schema) + output[column] = subschema + else: - output[column] = column_lower in schema + raise ValueError("Bad expected schema provided") return output - @abc.abstractmethod def validate_table_schema( - self, expected: dict[str, list[str]], schema: list[tuple] + self, expected: dict[str, list], schema: list[tuple] ) -> dict: """Public interface for investigating if fields are in a table schema. + expected is a dictionary of string column names to *something*: + - falsy (like None or []): just check that the column exists + - list of strings: check all the column children exist + - dict of a new child 'expected' dictionary, with same above rules + This method should lightly format results and pass them to - _parse_found_schema(), or a more bespoke table analysis function if needed. + parse_found_schema(), or a more bespoke table analysis function if needed. """ + parsed_schema = self.parse_found_schema(dict(schema)) + return self._recursively_validate(expected, parsed_schema) class DatabaseBackend(abc.ABC): @@ -179,11 +197,53 @@ def close(self) -> None: class AthenaParser(DatabaseParser): - def validate_table_schema( - self, expected: dict[dict[list]], schema: list[list] - ) -> dict: - schema = dict(schema) - return self._parse_found_schema(expected, schema) + def _find_type_len(self, row: str) -> int: + """Finds the end of a type string like row(...) or array(row(...))""" + # Note that this assumes the string is well formatted. + depth = 0 + for i in range(len(row)): + match row[i]: + case ",": + if depth == 0: + break + case "(": + depth += 1 + case ")": + depth -= 1 + return i + + def _split_row(self, row: str) -> dict[str, str]: + # Must handle "name type, name row(...), name type, name row(...)" + result = {} + # Real athena doesn't add extra spaces, but our unit tests do for + # readability, so let's strip out whitespace as we parse. + while row := row.strip(): + name, remainder = row.split(" ", 1) + type_len = self._find_type_len(remainder) + result[name] = remainder[0:type_len] + row = remainder[type_len + 2 :] # skip comma and space + return result + + def parse_found_schema(self, schema: dict[str, str]) -> dict: + # A sample response for table `observation`, column `component`: + # array(row(code varchar, display varchar)), + # text varchar, id varchar) + parsed = {} + + for key, value in schema.items(): + # Strip arrays out, they don't affect the shape of our schema. + while value.startswith("array("): + value = value.removeprefix("array(") + value = value.removesuffix(")") + + if value.startswith("row("): + value = value.removeprefix("row(") + value = value.removesuffix(")") + parsed[key] = self.parse_found_schema(self._split_row(value)) + else: + parsed[key] = {} + + return parsed class DuckDatabaseBackend(DatabaseBackend): @@ -323,16 +383,26 @@ def close(self) -> None: class DuckDbParser(DatabaseParser): """Table parser for DuckDB schemas""" - def validate_table_schema( - self, expected: dict[dict[list]], schema: list[tuple] - ) -> dict: + def parse_found_schema(self, schema: dict[str, str]) -> dict: """parses a information_schema.tables query response for valid columns""" - schema = dict(schema) - # since we're defaulting to athena naming conventions elsewhere, - # we'll lower case all the keys - schema = {k.lower(): v for k, v in schema.items()} + parsed = {} + + for key, value in schema.items(): + if isinstance(value, str): + # DuckDB provides a parser to go from string -> type objects + value = duckdb.typing.DuckDBPyType(value) + + # Collapse lists to the contained value + if value.id == "list": + value = value.children[0][1] # [('child', CONTAINED_TYPE)] + + if value.id == "struct": + result = self.parse_found_schema(dict(value.children)) + else: + result = {} + parsed[key.lower()] = result - return self._parse_found_schema(expected, schema) + return parsed def _read_rows_from_table_dir(path: str) -> list[dict]: diff --git a/cumulus_library/statistics/counts.py b/cumulus_library/statistics/counts.py index 6dac7dc2..44050783 100644 --- a/cumulus_library/statistics/counts.py +++ b/cumulus_library/statistics/counts.py @@ -262,7 +262,7 @@ def write_counts(self, filepath: str): """ self.prepare_queries(cursor=None, schema=None) self.comment_queries() - self.write_queries(filename=filepath) + self.write_queries(path=Path(filepath)) def prepare_queries(self, cursor: object | None = None, schema: str | None = None): """Stub implementing abstract base class diff --git a/cumulus_library/studies/core/builder_condition.py b/cumulus_library/studies/core/builder_condition.py index 34362abd..38d5f77f 100644 --- a/cumulus_library/studies/core/builder_condition.py +++ b/cumulus_library/studies/core/builder_condition.py @@ -4,37 +4,10 @@ expected_table_cols = { "condition": { - "category": [ - "coding", - "code", - "display", - "system", - "userSelected", - "version", - "text", - ], - "clinicalstatus": [ - "coding", - "code", - "display", - "system", - "userSelected", - "version", - "text", - ], "id": [], "recordedDate": [], - "verificationstatus": [ - "coding", - "code", - "display", - "system", - "userSelected", - "version", - "text", - ], - "subject": ["reference", "display", "type"], - "encounter": ["reference", "display", "type"], + "subject": sql_utils.REFERENCE, + "encounter": sql_utils.REFERENCE, } } @@ -43,38 +16,62 @@ class CoreConditionBuilder(base_table_builder.BaseTableBuilder): display_text = "Creating Condition tables..." def denormalize_codes(self): - preferred_config = sql_utils.CodeableConceptConfig( - source_table="condition", - source_id="id", - column_hierarchy=[("code", dict)], - target_table="core__condition_codable_concepts_display", - filter_priority=True, - code_systems=[ - "http://snomed.info/sct", - "http://hl7.org/fhir/sid/icd-10-cm", - "http://hl7.org/fhir/sid/icd-9-cm", - "http://hl7.org/fhir/sid/icd-9-cm/diagnosis", - # EPIC specific systems - "urn:oid:1.2.840.114350.1.13.71.2.7.2.728286", - "urn:oid:1.2.840.114350.1.13.71.2.7.4.698084.10375", - # Spec allowed code of last resort - "http://terminology.hl7.org/CodeSystem/data-absent-reason", - ], - ) - self.queries.append( - base_templates.get_codeable_concept_denormalize_query(preferred_config) - ) - - all_config = sql_utils.CodeableConceptConfig( - source_table="condition", - source_id="id", - column_hierarchy=[("code", dict)], - target_table="core__condition_codable_concepts_all", - filter_priority=False, - ) - self.queries.append( - base_templates.get_codeable_concept_denormalize_query(all_config) - ) + configs = [ + sql_utils.CodeableConceptConfig( + source_table="condition", + column_hierarchy=[("category", list)], + target_table="core__condition_dn_category", + # This is an extensible binding, and US Core already suggests three + # different code systems to pull its recommended four values from. + # So let's not filter by system here. + ), + sql_utils.CodeableConceptConfig( + source_table="condition", + column_hierarchy=[("clinicalStatus", dict)], + target_table="core__condition_dn_clinical_status", + filter_priority=True, + code_systems=[ + # Restrict to just this required binding system + "http://terminology.hl7.org/CodeSystem/condition-clinical", + ], + ), + sql_utils.CodeableConceptConfig( + source_table="condition", + column_hierarchy=[("code", dict)], + target_table="core__condition_codable_concepts_display", + filter_priority=True, + code_systems=[ + "http://snomed.info/sct", + "http://hl7.org/fhir/sid/icd-10-cm", + "http://hl7.org/fhir/sid/icd-9-cm", + "http://hl7.org/fhir/sid/icd-9-cm/diagnosis", + # EPIC specific systems + "urn:oid:1.2.840.114350.1.13.71.2.7.2.728286", + "urn:oid:1.2.840.114350.1.13.71.2.7.4.698084.10375", + # Spec allowed code of last resort + "http://terminology.hl7.org/CodeSystem/data-absent-reason", + ], + ), + sql_utils.CodeableConceptConfig( + source_table="condition", + column_hierarchy=[("code", dict)], + target_table="core__condition_codable_concepts_all", + ), + sql_utils.CodeableConceptConfig( + source_table="condition", + column_hierarchy=[("verificationStatus", dict)], + target_table="core__condition_dn_verification_status", + filter_priority=True, + code_systems=[ + # Restrict to just this required binding system + "http://terminology.hl7.org/CodeSystem/condition-ver-status", + ], + ), + ] + self.queries += [ + base_templates.get_codeable_concept_denormalize_query(config) + for config in configs + ] def prepare_queries( self, @@ -85,7 +82,7 @@ def prepare_queries( **kwargs, ): self.denormalize_codes() - validated_schema = core_templates.validate_schema( + validated_schema = sql_utils.validate_schema( cursor, schema, expected_table_cols, parser ) self.queries.append( diff --git a/cumulus_library/studies/core/builder_documentreference.py b/cumulus_library/studies/core/builder_documentreference.py index 6f752068..ac63424f 100644 --- a/cumulus_library/studies/core/builder_documentreference.py +++ b/cumulus_library/studies/core/builder_documentreference.py @@ -5,12 +5,11 @@ expected_table_cols = { "documentreference": { "id": [], - "type": [], "status": [], + "date": [], "docStatus": [], - "subject": ["reference"], - "context": ["encounter", "period", "start"], - "category": [], + "subject": sql_utils.REFERENCE, + "context": {"encounter": sql_utils.REFERENCE, "period": ["start"]}, } } @@ -29,6 +28,7 @@ def prepare_queries( self.queries = sql_utils.denormalize_complex_objects( schema, cursor, + parser, [ sql_utils.CodeableConceptConfig( source_table="documentreference", @@ -58,10 +58,11 @@ def prepare_queries( source_id="id", column_hierarchy=[("content", list), ("format", dict)], target_table="core__documentreference_dn_format", + expected={"format": sql_utils.CODING}, ), ], ) - validated_schema = core_templates.validate_schema( + validated_schema = sql_utils.validate_schema( cursor, schema, expected_table_cols, parser ) self.queries.append( diff --git a/cumulus_library/studies/core/builder_encounter.py b/cumulus_library/studies/core/builder_encounter.py index c557e8af..8f383e66 100644 --- a/cumulus_library/studies/core/builder_encounter.py +++ b/cumulus_library/studies/core/builder_encounter.py @@ -6,24 +6,14 @@ expected_table_cols = { "encounter": { + "id": [], "status": [], "period": [ "start", "end", ], - "class": [ - "code", - "system", - "display", - "userSelected", - "version", - ], - "subject": [ - "reference", - "display", - "type", - ], - "id": [], + "class": sql_utils.CODING, + "subject": sql_utils.REFERENCE, }, "etl__completion": { "group_name": [], @@ -47,7 +37,7 @@ def __post_init__(self): class CoreEncounterBuilder(base_table_builder.BaseTableBuilder): display_text = "Creating Encounter tables..." - def denormalize_codes(self, schema, cursor): + def denormalize_codes(self, schema, cursor, parser): code_configs = [ EncConfig( column_hierarchy=[("type", list)], @@ -110,11 +100,11 @@ def denormalize_codes(self, schema, cursor): ("hospitalization", dict), ("dischargedisposition", dict), ], - filter_priority=False, + expected={"dischargedisposition": sql_utils.CODEABLE_CONCEPT}, ), ] self.queries += sql_utils.denormalize_complex_objects( - schema, cursor, code_configs + schema, cursor, parser, code_configs ) def prepare_queries( @@ -128,8 +118,9 @@ def prepare_queries( self.denormalize_codes( schema, cursor, + parser, ) - validated_schema = core_templates.validate_schema( + validated_schema = sql_utils.validate_schema( cursor, schema, expected_table_cols, parser ) self.queries += [ diff --git a/cumulus_library/studies/core/builder_medication.py b/cumulus_library/studies/core/builder_medication.py index 3f40a150..a788c800 100644 --- a/cumulus_library/studies/core/builder_medication.py +++ b/cumulus_library/studies/core/builder_medication.py @@ -1,6 +1,6 @@ """ Module for generating core medication table""" -from cumulus_library import base_table_builder, base_utils +from cumulus_library import base_table_builder, base_utils, databases from cumulus_library.studies.core.core_templates import core_templates from cumulus_library.template_sql import base_templates, sql_utils @@ -8,7 +8,7 @@ class MedicationBuilder(base_table_builder.BaseTableBuilder): display_text = "Creating Medication table..." - def _check_data_in_fields(self, cursor, schema: str): + def _check_data_in_fields(self, cursor, parser, schema: str): """Validates whether either observed medication source is present We opt to not use the core_templates.utils based version of @@ -37,6 +37,7 @@ def _check_data_in_fields(self, cursor, schema: str): source_table=table, hierarchy=[(inline_col, dict), ("coding", list)], cursor=cursor, + parser=parser, ) if data_types["inline"]: query = base_templates.get_column_datatype_query( @@ -56,8 +57,9 @@ def _check_data_in_fields(self, cursor, schema: str): schema=schema, source_table=table, hierarchy=[("medicationreference", dict), ("reference", dict)], - expected=["reference"], + expected=sql_utils.REFERENCE, cursor=cursor, + parser=parser, ): return data_types, has_userselected @@ -83,15 +85,22 @@ def _check_data_in_fields(self, cursor, schema: str): return data_types, has_userselected - def prepare_queries(self, cursor: object, schema: str, *args, **kwargs) -> dict: + def prepare_queries( + self, + cursor: databases.DatabaseCursor, + schema: str, + parser: databases.DatabaseParser = None, + *args, + **kwargs, + ) -> dict: """Constructs queries related to condition codeableConcept :param cursor: A database cursor object :param schema: the schema/db name, matching the cursor - + :param parser: A database parser """ medication_datasources, has_userselected = self._check_data_in_fields( - cursor, schema + cursor, parser, schema ) if ( medication_datasources["inline"] diff --git a/cumulus_library/studies/core/builder_medicationrequest.py b/cumulus_library/studies/core/builder_medicationrequest.py index dbdde40b..1a46802e 100644 --- a/cumulus_library/studies/core/builder_medicationrequest.py +++ b/cumulus_library/studies/core/builder_medicationrequest.py @@ -14,10 +14,8 @@ "intent": [], "authoredOn": [], "reportedBoolean": [], - "category": ["code", "system", "display"], - "medicationCodeableConcept": ["code", "system", "display"], - "subject": ["reference"], - "encounter": ["reference"], + "subject": sql_utils.REFERENCE, + "encounter": sql_utils.REFERENCE, "dosageInstruction": ["text"], } } @@ -54,9 +52,9 @@ def prepare_queries( ), ] self.queries += sql_utils.denormalize_complex_objects( - schema, cursor, code_sources + schema, cursor, parser, code_sources ) - validated_schema = core_templates.validate_schema( + validated_schema = sql_utils.validate_schema( cursor, schema, expected_table_cols, parser ) self.queries.append( diff --git a/cumulus_library/studies/core/builder_observation.py b/cumulus_library/studies/core/builder_observation.py index e16a02cc..1258e127 100644 --- a/cumulus_library/studies/core/builder_observation.py +++ b/cumulus_library/studies/core/builder_observation.py @@ -9,25 +9,15 @@ expected_table_cols = { "observation": { "id": [], - "category": ["coding", "code", "display", "system", "text"], + "component": { + "valueQuantity": ["code", "comparator", "system", "unit", "value"], + }, "status": [], - "code": ["coding", "code", "display", "system", "text"], - "interpretation": ["coding", "code", "display", "system", "text"], - "referenceRange": [ - "low", - "high", - "normalValue", - "type", - "appliesTo", - "age", - "text", - ], "effectiveDateTime": [], - "valueQuantity": ["value", "comparator", "unit", "system", "code"], - "valueCodeableConcept": ["coding", "code", "display", "system"], + "valueQuantity": ["code", "comparator", "system", "unit", "value"], "valueString": [], - "subject": ["reference"], - "encounter": ["reference"], + "subject": sql_utils.REFERENCE, + "encounter": sql_utils.REFERENCE, } } @@ -35,9 +25,15 @@ @dataclass(kw_only=True) class ObsConfig(sql_utils.CodeableConceptConfig): source_table: str = "observation" + is_public: bool = False def __post_init__(self): - self.target_table = f"core__observation_dn_{self.column_hierarchy[-1][0]}" + # Consideration for future: should all denormalized tables be public? + # For now, we'll mark the ones we want to encourage use of, + # and for those, remove the maybe-confusing denormalization tag. + table_suffix = "" if self.is_public else "dn_" + table_suffix += "_".join(c[0] for c in self.column_hierarchy) + self.target_table = f"core__observation_{table_suffix}" class ObservationBuilder(base_table_builder.BaseTableBuilder): @@ -59,6 +55,26 @@ def prepare_queries( code_sources = [ ObsConfig(column_hierarchy=[("category", list)], filter_priority=False), ObsConfig(column_hierarchy=[("code", dict)], filter_priority=False), + ObsConfig( + is_public=True, + column_hierarchy=[("component", list), ("code", dict)], + expected={"code": sql_utils.CODEABLE_CONCEPT}, + ), + ObsConfig( + is_public=True, + column_hierarchy=[("component", list), ("dataabsentreason", dict)], + expected={"dataabsentreason": sql_utils.CODEABLE_CONCEPT}, + ), + ObsConfig( + is_public=True, + column_hierarchy=[("component", list), ("interpretation", list)], + expected={"interpretation": sql_utils.CODEABLE_CONCEPT}, + ), + ObsConfig( + is_public=True, + column_hierarchy=[("component", list), ("valuecodeableconcept", dict)], + expected={"valuecodeableconcept": sql_utils.CODEABLE_CONCEPT}, + ), ObsConfig( column_hierarchy=[("interpretation", list)], filter_priority=False ), @@ -73,11 +89,14 @@ def prepare_queries( ] self.queries += sql_utils.denormalize_complex_objects( - schema, cursor, code_sources + schema, cursor, parser, code_sources ) - validated_schema = core_templates.validate_schema( + validated_schema = sql_utils.validate_schema( cursor, schema, expected_table_cols, parser ) - self.queries.append( - core_templates.get_core_template("observation", validated_schema) - ) + self.queries += [ + core_templates.get_core_template("observation", validated_schema), + core_templates.get_core_template( + "observation_component_valuequantity", validated_schema + ), + ] diff --git a/cumulus_library/studies/core/builder_patient.py b/cumulus_library/studies/core/builder_patient.py index 7f5ee313..253515df 100644 --- a/cumulus_library/studies/core/builder_patient.py +++ b/cumulus_library/studies/core/builder_patient.py @@ -9,7 +9,7 @@ "patient": { "id": [], "gender": [], - "address": [], + "address": {"postalCode": {}}, "birthDate": [], } } @@ -53,7 +53,7 @@ def prepare_queries( is_array=True, ) self.queries.append(base_templates.get_extension_denormalize_query(config)) - validated_schema = core_templates.validate_schema( + validated_schema = sql_utils.validate_schema( cursor, schema, expected_table_cols, parser ) self.queries.append( diff --git a/cumulus_library/studies/core/core_templates/condition.sql.jinja b/cumulus_library/studies/core/core_templates/condition.sql.jinja index aae03c4a..16a94b6a 100644 --- a/cumulus_library/studies/core/core_templates/condition.sql.jinja +++ b/cumulus_library/studies/core/core_templates/condition.sql.jinja @@ -17,7 +17,6 @@ WITH temp_condition AS ( 'condition', 'c', [ - 'category', ('subject', 'reference', 'subject_ref'), ('encounter', 'reference', 'encounter_ref'), ], @@ -54,17 +53,16 @@ WITH temp_condition AS ( ], schema ) - }}, - c.verificationStatus, - c.clinicalStatus + }} FROM condition AS c LEFT JOIN core__condition_codable_concepts_all AS cca ON c.id = cca.id ) SELECT tc.id, - t_category_coding.category_row.code AS category_code, - t_category_coding.category_row.display AS category_display, + cdc.code AS category_code, + cdc.code_system AS category_code_system, + cdc.display AS category_display, tc.code, tc.code_system, tc.display AS code_display, @@ -75,13 +73,12 @@ SELECT tc.recordedDate_week, tc.recordedDate_month, tc.recordedDate_year, - t_clinicalStatus_coding.clinicalStatus_row.code AS clinicalStatus_code, - t_verificationStatus_coding.verificationStatus_row.code AS verificationStatus_code -FROM temp_condition AS tc, - unnest(category) AS t_category (category_coding), - unnest(category_coding.coding) AS t_category_coding (category_row), - unnest(clinicalStatus.coding) AS t_clinicalStatus_coding (clinicalStatus_row), - unnest(verificationStatus.coding) - AS t_verificationStatus_coding (verificationStatus_row) - + {#- We don't expose code_system for these next two since we filter + down to a single system in the denormalization table #} + cdcs.code AS clinicalStatus_code, + cdvs.code AS verificationStatus_code +FROM temp_condition AS tc +LEFT JOIN core__condition_dn_category AS cdc ON tc.id = cdc.id +LEFT JOIN core__condition_dn_clinical_status AS cdcs ON tc.id = cdcs.id +LEFT JOIN core__condition_dn_verification_status AS cdvs ON tc.id = cdvs.id WHERE tc.recordedDate BETWEEN date('2016-01-01') AND current_date; diff --git a/cumulus_library/studies/core/core_templates/core_templates.py b/cumulus_library/studies/core/core_templates/core_templates.py index c946a960..8d11a325 100644 --- a/cumulus_library/studies/core/core_templates/core_templates.py +++ b/cumulus_library/studies/core/core_templates/core_templates.py @@ -12,14 +12,5 @@ def get_core_template( ) -> str: """Extracts code system details as a standalone table""" return base_templates.get_base_template( - target_table, path=pathlib.Path(__file__).parent, schema=schema, config=config + target_table, path=PATH, schema=schema, config=config ) - - -def validate_schema(cursor: object, schema: str, expected_table_cols, parser): - validated_schema = {} - for table, cols in expected_table_cols.items(): - query = base_templates.get_column_datatype_query(schema, table, cols.keys()) - table_schema = cursor.execute(query).fetchall() - validated_schema[table] = parser.validate_table_schema(cols, table_schema) - return validated_schema diff --git a/cumulus_library/studies/core/core_templates/core_utils.jinja b/cumulus_library/studies/core/core_templates/core_utils.jinja index 66a56ed9..9dab57c1 100644 --- a/cumulus_library/studies/core/core_templates/core_utils.jinja +++ b/cumulus_library/studies/core/core_templates/core_utils.jinja @@ -27,16 +27,16 @@ targets is an array expecting a data type of the following: {#- depth one nested column-#} {%- if col is not string and col|length ==3%} {%- if schema[table][col[0]][col[1]] %} - {{ alias }}.{{ col[0] }}.{{ col[1] }} AS {{col[2].lower()}} + {{ alias }}.{{ col[0] }}.{{ col[1] }} AS {{ col[2] }} {%- else %} - cast(NULL as varchar) AS {{ col[2].lower() }} + cast(NULL as varchar) AS {{ col[2] }} {%- endif %} {#- depth two nested column -#} {%- elif col is not string and col|length ==4%} - {%- if schema[table][col[0]][col[2]] %} - {{ alias }}.{{ col[0] }}.{{ col[1] }}.{{ col[2] }} AS {{col[3].lower()}} + {%- if schema[table][col[0]][col[1]][col[2]] %} + {{ alias }}.{{ col[0] }}.{{ col[1] }}.{{ col[2] }} AS {{ col[3] }} {%- else %} - cast(NULL as varchar) AS {{ col[3].lower()}} + cast(NULL as varchar) AS {{ col[3] }} {%- endif %} {#- SQL primitive column column-#} {%- elif schema[table][col] %} @@ -44,9 +44,9 @@ targets is an array expecting a data type of the following: {%- else %} {#- workaround for docref date-#} {%- if col == "date"%} - cast(NULL as timestamp) AS "{{ col.lower() }}" + cast(NULL as timestamp) AS "{{ col }}" {%- else %} - cast(NULL as varchar) AS {{ col.lower() }} + cast(NULL as varchar) AS {{ col }} {%- endif %} {%- endif %} {{- syntax.comma_delineate(loop) }} @@ -66,20 +66,20 @@ targets is an array expecting a data type of the following: {%- if schema[table][col[0]][col[1]] %} date(from_iso8601_timestamp({{ alias }}.{{ col[0] }}.{{ col[1] }})) AS {{ col[2] }} {%- else %} - cast(NULL AS date) AS {{ col[1].lower() }} + cast(NULL AS date) AS {{ col[1] }} {% endif %} {#- depth two nested column -#} {%- elif col is not string and col|length ==4%} - {%- if schema[table][col[0]][col[2]] %} + {%- if schema[table][col[0]][col[1]][col[2]] %} date(from_iso8601_timestamp({{ alias }}.{{ col[0] }}.{{ col[1] }}.{{ col[2] }})) AS {{col[3]}} {%- else %} - cast(NULL AS date) AS {{ col[3].lower() }} + cast(NULL AS date) AS {{ col[3] }} {%- endif %} {#- SQL primitive column column-#} {%- elif schema[table][col] %} date(from_iso8601_timestamp({{ alias }}.{{ col }})) AS {{ col }} {%- else %} - cast(NULL AS date) AS {{ col.lower() }} + cast(NULL AS date) AS {{ col }} {%- endif %} {{- syntax.comma_delineate(loop) }} {%- endfor %} @@ -103,7 +103,7 @@ targets is assumed to be a list of tuples of one of the following format: {% endif %} {#- depth two nested column -#} {%- elif col is not string and col|length ==5%} - {%- if schema[table][col[0]][col[2]] %} + {%- if schema[table][col[0]][col[1]][col[2]] %} date_trunc('{{ col[4] }}', date(from_iso8601_timestamp({{ alias }}."{{ col[0] }}"."{{ col[1] }}"."{{col[2]}}"))) AS {{ col[3] }} {%- else %} diff --git a/cumulus_library/studies/core/core_templates/documentreference.sql.jinja b/cumulus_library/studies/core/core_templates/documentreference.sql.jinja index 05b00c0d..360dff03 100644 --- a/cumulus_library/studies/core/core_templates/documentreference.sql.jinja +++ b/cumulus_library/studies/core/core_templates/documentreference.sql.jinja @@ -16,17 +16,21 @@ WITH temp_documentreference AS ( 'documentreference', 'dr', [ - 'type', 'status', - 'date', 'docStatus', - 'context', + 'context', ('subject', 'reference', 'subject_ref'), - ('context', 'period', 'start', 'author_date') ], schema ) }}, + {{- utils.date_cols_from_str( + 'documentreference', + 'dr', + ['date'], + schema + ) + }}, {{- utils.truncate_date_cols( 'documentreference', 'dr', @@ -54,7 +58,7 @@ temp_encounters AS ( SELECT tdr.id, -{% if schema["documentreference"]["context"]["encounter"] %} +{% if schema["documentreference"]["context"]["encounter"]["reference"] %} context_encounter.encounter.reference AS encounter_ref FROM temp_documentreference AS tdr, unnest(context.encounter) AS context_encounter (encounter) --noqa diff --git a/cumulus_library/studies/core/core_templates/encounter.sql.jinja b/cumulus_library/studies/core/core_templates/encounter.sql.jinja index 54fa8e8f..fa45c089 100644 --- a/cumulus_library/studies/core/core_templates/encounter.sql.jinja +++ b/cumulus_library/studies/core/core_templates/encounter.sql.jinja @@ -26,9 +26,9 @@ temp_encounter_nullable AS ( 'e', [ 'status', - 'class', + ('class', 'code', 'class_code'), + ('class', 'system', 'class_code_system'), ('subject', 'reference', 'subject_ref'), - 'period', ], schema ) @@ -46,7 +46,7 @@ temp_encounter_nullable AS ( 'encounter', 'e', [ - ('period','end', 'period_end_day', 'day'), + ('period', 'end', 'period_end_day', 'day'), ('period', 'start', 'period_start_day', 'day'), ('period', 'start', 'period_start_week', 'week'), ('period', 'start', 'period_start_month', 'month'), @@ -68,7 +68,8 @@ temp_encounter AS ( SELECT DISTINCT e.id, e.status, - e.class, + e.class_code, + e.class_code_system, e.subject_ref, e.period_start, e.period_start_day, @@ -134,7 +135,7 @@ SELECT DISTINCT concat('Encounter/', e.id) AS encounter_ref FROM temp_encounter AS e LEFT JOIN core__fhir_mapping_expected_act_encounter_code_v3 AS eac - ON e.class.code = eac.found + ON e.class_code = eac.found LEFT JOIN core__fhir_act_encounter_code_v3 AS ac ON eac.expected = ac.code INNER JOIN core__patient AS p ON e.subject_ref = p.subject_ref WHERE diff --git a/cumulus_library/studies/core/core_templates/medicationrequest.sql.jinja b/cumulus_library/studies/core/core_templates/medicationrequest.sql.jinja index 869c2dc9..8a6f0b53 100644 --- a/cumulus_library/studies/core/core_templates/medicationrequest.sql.jinja +++ b/cumulus_library/studies/core/core_templates/medicationrequest.sql.jinja @@ -34,7 +34,6 @@ WITH temp_mr AS ( 'mr', [ - 'display', 'reportedBoolean', 'dosageInstruction', ('subject', 'reference', 'subject_ref'), @@ -69,4 +68,4 @@ SELECT mr.subject_ref, mr.encounter_ref FROM temp_mr AS mr, - UNNEST(dosageInstruction) AS dose_row (dose_col) + UNNEST(mr.dosageInstruction) AS dose_row (dose_col) diff --git a/cumulus_library/studies/core/core_templates/observation.sql.jinja b/cumulus_library/studies/core/core_templates/observation.sql.jinja index 80682f0c..f7df60a7 100644 --- a/cumulus_library/studies/core/core_templates/observation.sql.jinja +++ b/cumulus_library/studies/core/core_templates/observation.sql.jinja @@ -16,11 +16,13 @@ WITH temp_observation AS ( 'observation', 'o', [ + ('encounter', 'reference', 'encounter_ref'), + ('subject', 'reference', 'subject_ref'), 'valueString', ('valueQuantity', 'value', 'valueQuantity_value'), ('valueQuantity', 'comparator', 'valueQuantity_comparator'), ('valueQuantity', 'unit', 'valueQuantity_unit'), - ('valueQuantity', 'system', 'valueQuantity_system'), + ('valueQuantity', 'system', 'valueQuantity_code_system'), ('valueQuantity', 'code', 'valueQuantity_code'), ], schema @@ -50,11 +52,7 @@ WITH temp_observation AS ( odvcc.display AS valueCodeableConcept_display, odda.code AS dataAbsentReason_code, odda.code_system AS dataAbsentReason_code_system, - odda.display AS dataAbsentReason_display, - o.referencerange, - o.valueQuantity, - o.subject.reference AS subject_ref, - o.encounter.reference AS encounter_ref + odda.display AS dataAbsentReason_display FROM observation AS o LEFT JOIN core__observation_dn_category AS odcat ON o.id = odcat.id LEFT JOIN core__observation_dn_code AS odc ON o.id = odc.id @@ -83,7 +81,7 @@ SELECT valueQuantity_value, valueQuantity_comparator, valueQuantity_unit, - valueQuantity_system, + valueQuantity_code_system, valueQuantity_code, valueString, dataAbsentReason_code, diff --git a/cumulus_library/studies/core/core_templates/observation_component_valuequantity.sql.jinja b/cumulus_library/studies/core/core_templates/observation_component_valuequantity.sql.jinja new file mode 100644 index 00000000..fe64463d --- /dev/null +++ b/cumulus_library/studies/core/core_templates/observation_component_valuequantity.sql.jinja @@ -0,0 +1,66 @@ +{% import 'core_utils.jinja' as utils %} +{% import 'unnest_utils.jinja' as unnest_utils %} + +{#- Once we have generic denormalization code, this table could be re-written #} + +{#- If the database doesn't have valueQuantity fields at all, + we'll just skip this table. #} +{%- set quantity_schema = schema["observation"]["component"]["valueQuantity"] %} +{%- set has_value_quantity = ( + quantity_schema["value"] or quantity_schema["comparator"] or + quantity_schema["unit"] or quantity_schema["system"] or + quantity_schema["code"] +) %} + +CREATE TABLE core__observation_component_valuequantity AS ( + {%- if has_value_quantity %} + WITH + + flattened_rows AS ( + {{ unnest_utils.flatten('observation', 'component') }} + ), + + flattened_quantities AS ( + SELECT + f.id, + f.row, + {{- utils.nullable_cols( + 'observation', + 'f', + [ + ('component', 'valueQuantity', 'value', 'value'), + ('component', 'valueQuantity', 'comparator', 'comparator'), + ('component', 'valueQuantity', 'unit', 'unit'), + ('component', 'valueQuantity', 'system', 'code_system'), + ('component', 'valueQuantity', 'code', 'code'), + ], + schema + ) }} + FROM flattened_rows AS f + WHERE f.component.valueQuantity IS NOT NULL + ) + + SELECT + f.id, + f.row, + -- We ensure value is a double, because nullable_cols() above will cast + -- as varchar if value isn't in the schema. + CAST(f.value AS DOUBLE) AS value, -- noqa: disable=L029 + f.comparator, + f.unit, + f.code_system, + f.code + FROM flattened_quantities AS f + + {%- else %} + SELECT + 'x' AS id, + CAST(NULL AS BIGINT) AS row, + CAST(NULL AS DOUBLE) AS value, -- noqa: disable=L029 + 'x' AS comparator, + 'x' AS unit, + 'x' AS code_system, + 'x' AS code, + WHERE 1=0 -- empty table + {%- endif %} +); diff --git a/cumulus_library/studies/core/observation_type.sql b/cumulus_library/studies/core/observation_type.sql index a3c01bb5..bee4199a 100644 --- a/cumulus_library/studies/core/observation_type.sql +++ b/cumulus_library/studies/core/observation_type.sql @@ -1,3 +1,7 @@ +-- This file should be replaced with programmatic builders at some point. +-- But for now, while we create the cow paths of this pattern, they're manual. +-- We can pave them later. + CREATE TABLE core__observation_lab AS SELECT co.id, @@ -33,6 +37,11 @@ SELECT co.valueCodeableConcept_code, co.valueCodeableConcept_code_system, co.valueCodeableConcept_display, + co.valueQuantity_value, + co.valueQuantity_comparator, + co.valueQuantity_unit, + co.valueQuantity_code_system, + co.valueQuantity_code, co.status, co.interpretation_code, co.interpretation_code_system, diff --git a/cumulus_library/studies/core/reference_sql/builder_condition.sql b/cumulus_library/studies/core/reference_sql/builder_condition.sql index 2efbabee..fcb6b80f 100644 --- a/cumulus_library/studies/core/reference_sql/builder_condition.sql +++ b/cumulus_library/studies/core/reference_sql/builder_condition.sql @@ -4,6 +4,113 @@ -- and it may not be correct for all databases. Use the CLI's build -- option to derive the best SQL for your dataset. +-- ########################################################### + +CREATE TABLE core__condition_dn_category AS ( + WITH + + flattened_rows AS ( + SELECT DISTINCT + t.id AS id, + ROW_NUMBER() OVER (PARTITION BY id) AS row, + r."category" + FROM + condition AS t, + UNNEST(t."category") AS r ("category") + ), + + system_category_0 AS ( + SELECT DISTINCT + s.id AS id, + s.row, + u.codeable_concept.code, + u.codeable_concept.display, + u.codeable_concept.system AS code_system + FROM + flattened_rows AS s, + UNNEST(s.category.coding) AS u (codeable_concept) + ), --noqa: LT07 + + union_table AS ( + SELECT + id, + row, + code_system, + code, + display + FROM system_category_0 + + ) + SELECT + id, + row, + code, + code_system, + display + FROM union_table +); + + +-- ########################################################### + +CREATE TABLE core__condition_dn_clinical_status AS ( + WITH + + system_clinicalStatus_0 AS ( + SELECT DISTINCT + s.id AS id, + 0 AS row, + '0' AS priority, + u.codeable_concept.code, + u.codeable_concept.display, + u.codeable_concept.system AS code_system + FROM + condition AS s, + UNNEST(s.clinicalStatus.coding) AS u (codeable_concept) + WHERE + u.codeable_concept.system LIKE 'http://terminology.hl7.org/CodeSystem/condition-clinical' + ), --noqa: LT07 + + union_table AS ( + SELECT + id, + row, + priority, + code_system, + code, + display + FROM system_clinicalStatus_0 + + ), + + partitioned_table AS ( + SELECT + id, + row, + code, + code_system, + display, + priority, + ROW_NUMBER() + OVER ( + PARTITION BY id + ORDER BY priority ASC + ) AS available_priority + FROM union_table + GROUP BY id, row, priority, code_system, code, display + ORDER BY priority ASC + ) + + SELECT + id, + code, + code_system, + display + FROM partitioned_table + WHERE available_priority = 1 +); + + -- ########################################################### CREATE TABLE core__condition_codable_concepts_display AS ( @@ -12,6 +119,7 @@ CREATE TABLE core__condition_codable_concepts_display AS ( system_code_0 AS ( SELECT DISTINCT s.id AS id, + 0 AS row, '0' AS priority, u.codeable_concept.code, u.codeable_concept.display, @@ -26,6 +134,7 @@ CREATE TABLE core__condition_codable_concepts_display AS ( system_code_1 AS ( SELECT DISTINCT s.id AS id, + 0 AS row, '1' AS priority, u.codeable_concept.code, u.codeable_concept.display, @@ -40,6 +149,7 @@ CREATE TABLE core__condition_codable_concepts_display AS ( system_code_2 AS ( SELECT DISTINCT s.id AS id, + 0 AS row, '2' AS priority, u.codeable_concept.code, u.codeable_concept.display, @@ -54,6 +164,7 @@ CREATE TABLE core__condition_codable_concepts_display AS ( system_code_3 AS ( SELECT DISTINCT s.id AS id, + 0 AS row, '3' AS priority, u.codeable_concept.code, u.codeable_concept.display, @@ -68,6 +179,7 @@ CREATE TABLE core__condition_codable_concepts_display AS ( system_code_4 AS ( SELECT DISTINCT s.id AS id, + 0 AS row, '4' AS priority, u.codeable_concept.code, u.codeable_concept.display, @@ -82,6 +194,7 @@ CREATE TABLE core__condition_codable_concepts_display AS ( system_code_5 AS ( SELECT DISTINCT s.id AS id, + 0 AS row, '5' AS priority, u.codeable_concept.code, u.codeable_concept.display, @@ -96,6 +209,7 @@ CREATE TABLE core__condition_codable_concepts_display AS ( system_code_6 AS ( SELECT DISTINCT s.id AS id, + 0 AS row, '6' AS priority, u.codeable_concept.code, u.codeable_concept.display, @@ -110,6 +224,7 @@ CREATE TABLE core__condition_codable_concepts_display AS ( union_table AS ( SELECT id, + row, priority, code_system, code, @@ -118,6 +233,7 @@ CREATE TABLE core__condition_codable_concepts_display AS ( UNION SELECT id, + row, priority, code_system, code, @@ -126,6 +242,7 @@ CREATE TABLE core__condition_codable_concepts_display AS ( UNION SELECT id, + row, priority, code_system, code, @@ -134,6 +251,7 @@ CREATE TABLE core__condition_codable_concepts_display AS ( UNION SELECT id, + row, priority, code_system, code, @@ -142,6 +260,7 @@ CREATE TABLE core__condition_codable_concepts_display AS ( UNION SELECT id, + row, priority, code_system, code, @@ -150,6 +269,7 @@ CREATE TABLE core__condition_codable_concepts_display AS ( UNION SELECT id, + row, priority, code_system, code, @@ -158,6 +278,7 @@ CREATE TABLE core__condition_codable_concepts_display AS ( UNION SELECT id, + row, priority, code_system, code, @@ -169,6 +290,7 @@ CREATE TABLE core__condition_codable_concepts_display AS ( partitioned_table AS ( SELECT id, + row, code, code_system, display, @@ -179,7 +301,7 @@ CREATE TABLE core__condition_codable_concepts_display AS ( ORDER BY priority ASC ) AS available_priority FROM union_table - GROUP BY id, priority, code_system, code, display + GROUP BY id, row, priority, code_system, code, display ORDER BY priority ASC ) @@ -201,6 +323,7 @@ CREATE TABLE core__condition_codable_concepts_all AS ( system_code_0 AS ( SELECT DISTINCT s.id AS id, + 0 AS row, u.codeable_concept.code, u.codeable_concept.display, u.codeable_concept.system AS code_system @@ -212,6 +335,7 @@ CREATE TABLE core__condition_codable_concepts_all AS ( union_table AS ( SELECT id, + row, code_system, code, display @@ -227,6 +351,66 @@ CREATE TABLE core__condition_codable_concepts_all AS ( ); +-- ########################################################### + +CREATE TABLE core__condition_dn_verification_status AS ( + WITH + + system_verificationStatus_0 AS ( + SELECT DISTINCT + s.id AS id, + 0 AS row, + '0' AS priority, + u.codeable_concept.code, + u.codeable_concept.display, + u.codeable_concept.system AS code_system + FROM + condition AS s, + UNNEST(s.verificationStatus.coding) AS u (codeable_concept) + WHERE + u.codeable_concept.system LIKE 'http://terminology.hl7.org/CodeSystem/condition-ver-status' + ), --noqa: LT07 + + union_table AS ( + SELECT + id, + row, + priority, + code_system, + code, + display + FROM system_verificationStatus_0 + + ), + + partitioned_table AS ( + SELECT + id, + row, + code, + code_system, + display, + priority, + ROW_NUMBER() + OVER ( + PARTITION BY id + ORDER BY priority ASC + ) AS available_priority + FROM union_table + GROUP BY id, row, priority, code_system, code, display + ORDER BY priority ASC + ) + + SELECT + id, + code, + code_system, + display + FROM partitioned_table + WHERE available_priority = 1 +); + + -- ########################################################### @@ -256,8 +440,9 @@ WITH temp_condition AS ( SELECT tc.id, - t_category_coding.category_row.code AS category_code, - t_category_coding.category_row.display AS category_display, + cdc.code AS category_code, + cdc.code_system AS category_code_system, + cdc.display AS category_display, tc.code, tc.code_system, tc.display AS code_display, @@ -268,13 +453,10 @@ SELECT tc.recordedDate_week, tc.recordedDate_month, tc.recordedDate_year, - t_clinicalStatus_coding.clinicalStatus_row.code AS clinicalStatus_code, - t_verificationStatus_coding.verificationStatus_row.code AS verificationStatus_code -FROM temp_condition AS tc, - unnest(category) AS t_category (category_coding), - unnest(category_coding.coding) AS t_category_coding (category_row), - unnest(clinicalStatus.coding) AS t_clinicalStatus_coding (clinicalStatus_row), - unnest(verificationStatus.coding) - AS t_verificationStatus_coding (verificationStatus_row) - + cdcs.code AS clinicalStatus_code, + cdvs.code AS verificationStatus_code +FROM temp_condition AS tc +LEFT JOIN core__condition_dn_category AS cdc ON tc.id = cdc.id +LEFT JOIN core__condition_dn_clinical_status AS cdcs ON tc.id = cdcs.id +LEFT JOIN core__condition_dn_verification_status AS cdvs ON tc.id = cdvs.id WHERE tc.recordedDate BETWEEN date('2016-01-01') AND current_date; diff --git a/cumulus_library/studies/core/reference_sql/builder_documentreference.sql b/cumulus_library/studies/core/reference_sql/builder_documentreference.sql index d0229200..afeb8ca8 100644 --- a/cumulus_library/studies/core/reference_sql/builder_documentreference.sql +++ b/cumulus_library/studies/core/reference_sql/builder_documentreference.sql @@ -12,6 +12,7 @@ CREATE TABLE core__documentreference_dn_type AS ( system_type_0 AS ( SELECT DISTINCT s.id AS id, + 0 AS row, u.codeable_concept.code, u.codeable_concept.display, u.codeable_concept.system AS code_system @@ -23,6 +24,7 @@ CREATE TABLE core__documentreference_dn_type AS ( union_table AS ( SELECT id, + row, code_system, code, display @@ -43,17 +45,27 @@ CREATE TABLE core__documentreference_dn_type AS ( CREATE TABLE core__documentreference_dn_category AS ( WITH + flattened_rows AS ( + SELECT DISTINCT + t.id AS id, + ROW_NUMBER() OVER (PARTITION BY id) AS row, + r."category" + FROM + documentreference AS t, + UNNEST(t."category") AS r ("category") + ), + system_category_0 AS ( SELECT DISTINCT s.id AS id, + s.row, '0' AS priority, u.codeable_concept.code, u.codeable_concept.display, u.codeable_concept.system AS code_system FROM - documentreference AS s, - UNNEST(s.category) AS cc (cc_row), - UNNEST(cc.cc_row.coding) AS u (codeable_concept) + flattened_rows AS s, + UNNEST(s.category.coding) AS u (codeable_concept) WHERE u.codeable_concept.system LIKE 'http://hl7.org/fhir/us/core/ValueSet/us-core-documentreference-category' ), --noqa: LT07 @@ -61,6 +73,7 @@ CREATE TABLE core__documentreference_dn_category AS ( union_table AS ( SELECT id, + row, priority, code_system, code, @@ -72,6 +85,7 @@ CREATE TABLE core__documentreference_dn_category AS ( partitioned_table AS ( SELECT id, + row, code, code_system, display, @@ -82,12 +96,13 @@ CREATE TABLE core__documentreference_dn_category AS ( ORDER BY priority ASC ) AS available_priority FROM union_table - GROUP BY id, priority, code_system, code, display + GROUP BY id, row, priority, code_system, code, display ORDER BY priority ASC ) SELECT id, + row, code, code_system, display @@ -140,11 +155,10 @@ WITH temp_documentreference AS ( dr.id, dr.type, dr.status, - cast(NULL as timestamp) AS "date", dr.docStatus, dr.context, dr.subject.reference AS subject_ref, - dr.context.period.start AS author_date, + date(from_iso8601_timestamp(dr.date)) AS date, date_trunc('day', date(from_iso8601_timestamp(dr."context"."period"."start"))) AS author_day, date_trunc('week', date(from_iso8601_timestamp(dr."context"."period"."start"))) diff --git a/cumulus_library/studies/core/reference_sql/builder_encounter.sql b/cumulus_library/studies/core/reference_sql/builder_encounter.sql index 43bebd80..8ae6ba58 100644 --- a/cumulus_library/studies/core/reference_sql/builder_encounter.sql +++ b/cumulus_library/studies/core/reference_sql/builder_encounter.sql @@ -9,17 +9,27 @@ CREATE TABLE core__encounter_dn_type AS ( WITH + flattened_rows AS ( + SELECT DISTINCT + t.id AS id, + ROW_NUMBER() OVER (PARTITION BY id) AS row, + r."type" + FROM + encounter AS t, + UNNEST(t."type") AS r ("type") + ), + system_type_0 AS ( SELECT DISTINCT s.id AS id, + s.row, '0' AS priority, u.codeable_concept.code, u.codeable_concept.display, u.codeable_concept.system AS code_system FROM - encounter AS s, - UNNEST(s.type) AS cc (cc_row), - UNNEST(cc.cc_row.coding) AS u (codeable_concept) + flattened_rows AS s, + UNNEST(s.type.coding) AS u (codeable_concept) WHERE u.codeable_concept.system LIKE 'http://terminology.hl7.org/CodeSystem/encounter-type' ), --noqa: LT07 @@ -27,14 +37,14 @@ CREATE TABLE core__encounter_dn_type AS ( system_type_1 AS ( SELECT DISTINCT s.id AS id, + s.row, '1' AS priority, u.codeable_concept.code, u.codeable_concept.display, u.codeable_concept.system AS code_system FROM - encounter AS s, - UNNEST(s.type) AS cc (cc_row), - UNNEST(cc.cc_row.coding) AS u (codeable_concept) + flattened_rows AS s, + UNNEST(s.type.coding) AS u (codeable_concept) WHERE u.codeable_concept.system LIKE 'http://terminology.hl7.org/CodeSystem/v2-0004' ), --noqa: LT07 @@ -42,14 +52,14 @@ CREATE TABLE core__encounter_dn_type AS ( system_type_2 AS ( SELECT DISTINCT s.id AS id, + s.row, '2' AS priority, u.codeable_concept.code, u.codeable_concept.display, u.codeable_concept.system AS code_system FROM - encounter AS s, - UNNEST(s.type) AS cc (cc_row), - UNNEST(cc.cc_row.coding) AS u (codeable_concept) + flattened_rows AS s, + UNNEST(s.type.coding) AS u (codeable_concept) WHERE u.codeable_concept.system LIKE 'urn:oid:2.16.840.1.113883.4.642.3.248' ), --noqa: LT07 @@ -57,14 +67,14 @@ CREATE TABLE core__encounter_dn_type AS ( system_type_3 AS ( SELECT DISTINCT s.id AS id, + s.row, '3' AS priority, u.codeable_concept.code, u.codeable_concept.display, u.codeable_concept.system AS code_system FROM - encounter AS s, - UNNEST(s.type) AS cc (cc_row), - UNNEST(cc.cc_row.coding) AS u (codeable_concept) + flattened_rows AS s, + UNNEST(s.type.coding) AS u (codeable_concept) WHERE u.codeable_concept.system LIKE 'http://snomed.info/sct' ), --noqa: LT07 @@ -72,14 +82,14 @@ CREATE TABLE core__encounter_dn_type AS ( system_type_4 AS ( SELECT DISTINCT s.id AS id, + s.row, '4' AS priority, u.codeable_concept.code, u.codeable_concept.display, u.codeable_concept.system AS code_system FROM - encounter AS s, - UNNEST(s.type) AS cc (cc_row), - UNNEST(cc.cc_row.coding) AS u (codeable_concept) + flattened_rows AS s, + UNNEST(s.type.coding) AS u (codeable_concept) WHERE u.codeable_concept.system LIKE 'https://fhir.cerner.com/%/codeSet/71' ), --noqa: LT07 @@ -87,14 +97,14 @@ CREATE TABLE core__encounter_dn_type AS ( system_type_5 AS ( SELECT DISTINCT s.id AS id, + s.row, '5' AS priority, u.codeable_concept.code, u.codeable_concept.display, u.codeable_concept.system AS code_system FROM - encounter AS s, - UNNEST(s.type) AS cc (cc_row), - UNNEST(cc.cc_row.coding) AS u (codeable_concept) + flattened_rows AS s, + UNNEST(s.type.coding) AS u (codeable_concept) WHERE u.codeable_concept.system LIKE 'urn:oid:1.2.840.114350.1.13.71.2.7.10.698084.10110' ), --noqa: LT07 @@ -102,14 +112,14 @@ CREATE TABLE core__encounter_dn_type AS ( system_type_6 AS ( SELECT DISTINCT s.id AS id, + s.row, '6' AS priority, u.codeable_concept.code, u.codeable_concept.display, u.codeable_concept.system AS code_system FROM - encounter AS s, - UNNEST(s.type) AS cc (cc_row), - UNNEST(cc.cc_row.coding) AS u (codeable_concept) + flattened_rows AS s, + UNNEST(s.type.coding) AS u (codeable_concept) WHERE u.codeable_concept.system LIKE 'urn:oid:1.2.840.114350.1.13.71.2.7.10.698084.18875' ), --noqa: LT07 @@ -117,14 +127,14 @@ CREATE TABLE core__encounter_dn_type AS ( system_type_7 AS ( SELECT DISTINCT s.id AS id, + s.row, '7' AS priority, u.codeable_concept.code, u.codeable_concept.display, u.codeable_concept.system AS code_system FROM - encounter AS s, - UNNEST(s.type) AS cc (cc_row), - UNNEST(cc.cc_row.coding) AS u (codeable_concept) + flattened_rows AS s, + UNNEST(s.type.coding) AS u (codeable_concept) WHERE u.codeable_concept.system LIKE 'urn:oid:1.2.840.114350.1.13.71.2.7.10.698084.30' ), --noqa: LT07 @@ -132,14 +142,14 @@ CREATE TABLE core__encounter_dn_type AS ( system_type_8 AS ( SELECT DISTINCT s.id AS id, + s.row, '8' AS priority, u.codeable_concept.code, u.codeable_concept.display, u.codeable_concept.system AS code_system FROM - encounter AS s, - UNNEST(s.type) AS cc (cc_row), - UNNEST(cc.cc_row.coding) AS u (codeable_concept) + flattened_rows AS s, + UNNEST(s.type.coding) AS u (codeable_concept) WHERE u.codeable_concept.system LIKE 'urn:oid:1.2.840.114350.1.13.71.2.7.2.808267' ), --noqa: LT07 @@ -147,6 +157,7 @@ CREATE TABLE core__encounter_dn_type AS ( union_table AS ( SELECT id, + row, priority, code_system, code, @@ -155,6 +166,7 @@ CREATE TABLE core__encounter_dn_type AS ( UNION SELECT id, + row, priority, code_system, code, @@ -163,6 +175,7 @@ CREATE TABLE core__encounter_dn_type AS ( UNION SELECT id, + row, priority, code_system, code, @@ -171,6 +184,7 @@ CREATE TABLE core__encounter_dn_type AS ( UNION SELECT id, + row, priority, code_system, code, @@ -179,6 +193,7 @@ CREATE TABLE core__encounter_dn_type AS ( UNION SELECT id, + row, priority, code_system, code, @@ -187,6 +202,7 @@ CREATE TABLE core__encounter_dn_type AS ( UNION SELECT id, + row, priority, code_system, code, @@ -195,6 +211,7 @@ CREATE TABLE core__encounter_dn_type AS ( UNION SELECT id, + row, priority, code_system, code, @@ -203,6 +220,7 @@ CREATE TABLE core__encounter_dn_type AS ( UNION SELECT id, + row, priority, code_system, code, @@ -211,6 +229,7 @@ CREATE TABLE core__encounter_dn_type AS ( UNION SELECT id, + row, priority, code_system, code, @@ -222,6 +241,7 @@ CREATE TABLE core__encounter_dn_type AS ( partitioned_table AS ( SELECT id, + row, code, code_system, display, @@ -232,12 +252,13 @@ CREATE TABLE core__encounter_dn_type AS ( ORDER BY priority ASC ) AS available_priority FROM union_table - GROUP BY id, priority, code_system, code, display + GROUP BY id, row, priority, code_system, code, display ORDER BY priority ASC ) SELECT id, + row, code, code_system, display @@ -255,6 +276,7 @@ AS ( (cast(NULL AS varchar),cast(NULL AS varchar),cast(NULL AS varchar),cast(NULL AS varchar)) ) AS t ("id","code","code_system","display") + WHERE 1 = 0 -- ensure empty table ); -- ########################################################### @@ -266,6 +288,7 @@ AS ( (cast(NULL AS varchar),cast(NULL AS varchar),cast(NULL AS varchar),cast(NULL AS varchar)) ) AS t ("id","code","code_system","display") + WHERE 1 = 0 -- ensure empty table ); -- ########################################################### @@ -273,17 +296,27 @@ AS ( CREATE TABLE core__encounter_dn_reasoncode AS ( WITH + flattened_rows AS ( + SELECT DISTINCT + t.id AS id, + ROW_NUMBER() OVER (PARTITION BY id) AS row, + r."reasoncode" + FROM + encounter AS t, + UNNEST(t."reasoncode") AS r ("reasoncode") + ), + system_reasoncode_0 AS ( SELECT DISTINCT s.id AS id, + s.row, '0' AS priority, u.codeable_concept.code, u.codeable_concept.display, u.codeable_concept.system AS code_system FROM - encounter AS s, - UNNEST(s.reasoncode) AS cc (cc_row), - UNNEST(cc.cc_row.coding) AS u (codeable_concept) + flattened_rows AS s, + UNNEST(s.reasoncode.coding) AS u (codeable_concept) WHERE u.codeable_concept.system LIKE 'http://terminology.hl7.org/CodeSystem/v3-ActPriority' ), --noqa: LT07 @@ -291,14 +324,14 @@ CREATE TABLE core__encounter_dn_reasoncode AS ( system_reasoncode_1 AS ( SELECT DISTINCT s.id AS id, + s.row, '1' AS priority, u.codeable_concept.code, u.codeable_concept.display, u.codeable_concept.system AS code_system FROM - encounter AS s, - UNNEST(s.reasoncode) AS cc (cc_row), - UNNEST(cc.cc_row.coding) AS u (codeable_concept) + flattened_rows AS s, + UNNEST(s.reasoncode.coding) AS u (codeable_concept) WHERE u.codeable_concept.system LIKE 'http://snomed.info/sct' ), --noqa: LT07 @@ -306,14 +339,14 @@ CREATE TABLE core__encounter_dn_reasoncode AS ( system_reasoncode_2 AS ( SELECT DISTINCT s.id AS id, + s.row, '2' AS priority, u.codeable_concept.code, u.codeable_concept.display, u.codeable_concept.system AS code_system FROM - encounter AS s, - UNNEST(s.reasoncode) AS cc (cc_row), - UNNEST(cc.cc_row.coding) AS u (codeable_concept) + flattened_rows AS s, + UNNEST(s.reasoncode.coding) AS u (codeable_concept) WHERE u.codeable_concept.system LIKE 'http://hl7.org/fhir/sid/icd-10-cm' ), --noqa: LT07 @@ -321,14 +354,14 @@ CREATE TABLE core__encounter_dn_reasoncode AS ( system_reasoncode_3 AS ( SELECT DISTINCT s.id AS id, + s.row, '3' AS priority, u.codeable_concept.code, u.codeable_concept.display, u.codeable_concept.system AS code_system FROM - encounter AS s, - UNNEST(s.reasoncode) AS cc (cc_row), - UNNEST(cc.cc_row.coding) AS u (codeable_concept) + flattened_rows AS s, + UNNEST(s.reasoncode.coding) AS u (codeable_concept) WHERE u.codeable_concept.system LIKE 'http://hl7.org/fhir/sid/icd-9-cm' ), --noqa: LT07 @@ -336,14 +369,14 @@ CREATE TABLE core__encounter_dn_reasoncode AS ( system_reasoncode_4 AS ( SELECT DISTINCT s.id AS id, + s.row, '4' AS priority, u.codeable_concept.code, u.codeable_concept.display, u.codeable_concept.system AS code_system FROM - encounter AS s, - UNNEST(s.reasoncode) AS cc (cc_row), - UNNEST(cc.cc_row.coding) AS u (codeable_concept) + flattened_rows AS s, + UNNEST(s.reasoncode.coding) AS u (codeable_concept) WHERE u.codeable_concept.system LIKE 'https://fhir.cerner.com/%/nomenclature' ), --noqa: LT07 @@ -351,14 +384,14 @@ CREATE TABLE core__encounter_dn_reasoncode AS ( system_reasoncode_5 AS ( SELECT DISTINCT s.id AS id, + s.row, '5' AS priority, u.codeable_concept.code, u.codeable_concept.display, u.codeable_concept.system AS code_system FROM - encounter AS s, - UNNEST(s.reasoncode) AS cc (cc_row), - UNNEST(cc.cc_row.coding) AS u (codeable_concept) + flattened_rows AS s, + UNNEST(s.reasoncode.coding) AS u (codeable_concept) WHERE u.codeable_concept.system LIKE 'urn:oid:1.2.840.114350.1.13.71.2.7.2.728286' ), --noqa: LT07 @@ -366,6 +399,7 @@ CREATE TABLE core__encounter_dn_reasoncode AS ( union_table AS ( SELECT id, + row, priority, code_system, code, @@ -374,6 +408,7 @@ CREATE TABLE core__encounter_dn_reasoncode AS ( UNION SELECT id, + row, priority, code_system, code, @@ -382,6 +417,7 @@ CREATE TABLE core__encounter_dn_reasoncode AS ( UNION SELECT id, + row, priority, code_system, code, @@ -390,6 +426,7 @@ CREATE TABLE core__encounter_dn_reasoncode AS ( UNION SELECT id, + row, priority, code_system, code, @@ -398,6 +435,7 @@ CREATE TABLE core__encounter_dn_reasoncode AS ( UNION SELECT id, + row, priority, code_system, code, @@ -406,6 +444,7 @@ CREATE TABLE core__encounter_dn_reasoncode AS ( UNION SELECT id, + row, priority, code_system, code, @@ -417,6 +456,7 @@ CREATE TABLE core__encounter_dn_reasoncode AS ( partitioned_table AS ( SELECT id, + row, code, code_system, display, @@ -427,12 +467,13 @@ CREATE TABLE core__encounter_dn_reasoncode AS ( ORDER BY priority ASC ) AS available_priority FROM union_table - GROUP BY id, priority, code_system, code, display + GROUP BY id, row, priority, code_system, code, display ORDER BY priority ASC ) SELECT id, + row, code, code_system, display @@ -449,6 +490,7 @@ CREATE TABLE core__encounter_dn_dischargedisposition AS ( system_dischargedisposition_0 AS ( SELECT DISTINCT s.id AS id, + 0 AS row, u.codeable_concept.code, u.codeable_concept.display, u.codeable_concept.system AS code_system @@ -460,6 +502,7 @@ CREATE TABLE core__encounter_dn_dischargedisposition AS ( union_table AS ( SELECT id, + row, code_system, code, display diff --git a/cumulus_library/studies/core/reference_sql/builder_medicationrequest.sql b/cumulus_library/studies/core/reference_sql/builder_medicationrequest.sql index 0a47357d..52ee94bc 100644 --- a/cumulus_library/studies/core/reference_sql/builder_medicationrequest.sql +++ b/cumulus_library/studies/core/reference_sql/builder_medicationrequest.sql @@ -9,21 +9,32 @@ CREATE TABLE core__medicationrequest_dn_category AS ( WITH + flattened_rows AS ( + SELECT DISTINCT + t.id AS id, + ROW_NUMBER() OVER (PARTITION BY id) AS row, + r."category" + FROM + medicationrequest AS t, + UNNEST(t."category") AS r ("category") + ), + system_category_0 AS ( SELECT DISTINCT s.id AS id, + s.row, u.codeable_concept.code, u.codeable_concept.display, u.codeable_concept.system AS code_system FROM - medicationrequest AS s, - UNNEST(s.category) AS cc (cc_row), - UNNEST(cc.cc_row.coding) AS u (codeable_concept) + flattened_rows AS s, + UNNEST(s.category.coding) AS u (codeable_concept) ), --noqa: LT07 union_table AS ( SELECT id, + row, code_system, code, display @@ -32,6 +43,7 @@ CREATE TABLE core__medicationrequest_dn_category AS ( ) SELECT id, + row, code, code_system, display @@ -47,6 +59,7 @@ CREATE TABLE core__medicationrequest_dn_medication AS ( system_medicationcodeableconcept_0 AS ( SELECT DISTINCT s.id AS id, + 0 AS row, u.codeable_concept.code, u.codeable_concept.display, u.codeable_concept.system AS code_system @@ -58,6 +71,7 @@ CREATE TABLE core__medicationrequest_dn_medication AS ( union_table AS ( SELECT id, + row, code_system, code, display @@ -118,4 +132,4 @@ SELECT mr.subject_ref, mr.encounter_ref FROM temp_mr AS mr, - UNNEST(dosageInstruction) AS dose_row (dose_col) + UNNEST(mr.dosageInstruction) AS dose_row (dose_col) diff --git a/cumulus_library/studies/core/reference_sql/builder_observation.sql b/cumulus_library/studies/core/reference_sql/builder_observation.sql index 25244c50..d9f7a226 100644 --- a/cumulus_library/studies/core/reference_sql/builder_observation.sql +++ b/cumulus_library/studies/core/reference_sql/builder_observation.sql @@ -9,21 +9,32 @@ CREATE TABLE core__observation_dn_category AS ( WITH + flattened_rows AS ( + SELECT DISTINCT + t.id AS id, + ROW_NUMBER() OVER (PARTITION BY id) AS row, + r."category" + FROM + observation AS t, + UNNEST(t."category") AS r ("category") + ), + system_category_0 AS ( SELECT DISTINCT s.id AS id, + s.row, u.codeable_concept.code, u.codeable_concept.display, u.codeable_concept.system AS code_system FROM - observation AS s, - UNNEST(s.category) AS cc (cc_row), - UNNEST(cc.cc_row.coding) AS u (codeable_concept) + flattened_rows AS s, + UNNEST(s.category.coding) AS u (codeable_concept) ), --noqa: LT07 union_table AS ( SELECT id, + row, code_system, code, display @@ -32,6 +43,7 @@ CREATE TABLE core__observation_dn_category AS ( ) SELECT id, + row, code, code_system, display @@ -47,6 +59,7 @@ CREATE TABLE core__observation_dn_code AS ( system_code_0 AS ( SELECT DISTINCT s.id AS id, + 0 AS row, u.codeable_concept.code, u.codeable_concept.display, u.codeable_concept.system AS code_system @@ -58,6 +71,53 @@ CREATE TABLE core__observation_dn_code AS ( union_table AS ( SELECT id, + row, + code_system, + code, + display + FROM system_code_0 + + ) + SELECT + id, + code, + code_system, + display + FROM union_table +); + + +-- ########################################################### + +CREATE TABLE core__observation_component_code AS ( + WITH + + flattened_rows AS ( + SELECT DISTINCT + t.id AS id, + ROW_NUMBER() OVER (PARTITION BY id) AS row, + r."code" + FROM + observation AS t, + UNNEST(t."component") AS parent (r) + ), + + system_code_0 AS ( + SELECT DISTINCT + s.id AS id, + s.row, + u.codeable_concept.code, + u.codeable_concept.display, + u.codeable_concept.system AS code_system + FROM + flattened_rows AS s, + UNNEST(s.code.coding) AS u (codeable_concept) + ), --noqa: LT07 + + union_table AS ( + SELECT + id, + row, code_system, code, display @@ -66,6 +126,111 @@ CREATE TABLE core__observation_dn_code AS ( ) SELECT id, + row, + code, + code_system, + display + FROM union_table +); + + +-- ########################################################### + +CREATE TABLE core__observation_component_dataabsentreason AS ( + WITH + + flattened_rows AS ( + SELECT DISTINCT + t.id AS id, + ROW_NUMBER() OVER (PARTITION BY id) AS row, + r."dataabsentreason" + FROM + observation AS t, + UNNEST(t."component") AS parent (r) + ), + + system_dataabsentreason_0 AS ( + SELECT DISTINCT + s.id AS id, + s.row, + u.codeable_concept.code, + u.codeable_concept.display, + u.codeable_concept.system AS code_system + FROM + flattened_rows AS s, + UNNEST(s.dataabsentreason.coding) AS u (codeable_concept) + ), --noqa: LT07 + + union_table AS ( + SELECT + id, + row, + code_system, + code, + display + FROM system_dataabsentreason_0 + + ) + SELECT + id, + row, + code, + code_system, + display + FROM union_table +); + + +-- ########################################################### + +CREATE TABLE core__observation_component_interpretation AS ( + WITH + + flattened_rows AS ( + SELECT DISTINCT + t.id AS id, + ROW_NUMBER() OVER (PARTITION BY id) AS row, + r."interpretation" + FROM + observation AS t, + UNNEST(t."component") AS parent (r) + ), + + child_flattened_rows AS ( + SELECT DISTINCT + s.id, + s.row, -- keep the parent row number + u."interpretation" + FROM + flattened_rows AS s, + UNNEST(s."interpretation") AS u ("interpretation") + ), + + system_interpretation_0 AS ( + SELECT DISTINCT + s.id AS id, + s.row, + u.codeable_concept.code, + u.codeable_concept.display, + u.codeable_concept.system AS code_system + FROM + child_flattened_rows AS s, + UNNEST(s.interpretation.coding) AS u (codeable_concept) + ), --noqa: LT07 + + union_table AS ( + SELECT + id, + row, + code_system, + code, + display + FROM system_interpretation_0 + + ) + SELECT + id, + row, code, code_system, display @@ -73,6 +238,18 @@ CREATE TABLE core__observation_dn_code AS ( ); +-- ########################################################### + +CREATE TABLE IF NOT EXISTS "main"."core__observation_component_valuecodeableconcept" +AS ( + SELECT * FROM ( + VALUES + (cast(NULL AS varchar),cast(NULL AS varchar),cast(NULL AS varchar),cast(NULL AS varchar)) + ) + AS t ("id","code","code_system","display") + WHERE 1 = 0 -- ensure empty table +); + -- ########################################################### CREATE TABLE IF NOT EXISTS "main"."core__observation_dn_interpretation" @@ -82,6 +259,7 @@ AS ( (cast(NULL AS varchar),cast(NULL AS varchar),cast(NULL AS varchar),cast(NULL AS varchar)) ) AS t ("id","code","code_system","display") + WHERE 1 = 0 -- ensure empty table ); -- ########################################################### @@ -92,6 +270,7 @@ CREATE TABLE core__observation_dn_valuecodeableconcept AS ( system_valuecodeableconcept_0 AS ( SELECT DISTINCT s.id AS id, + 0 AS row, u.codeable_concept.code, u.codeable_concept.display, u.codeable_concept.system AS code_system @@ -103,6 +282,7 @@ CREATE TABLE core__observation_dn_valuecodeableconcept AS ( union_table AS ( SELECT id, + row, code_system, code, display @@ -127,6 +307,7 @@ AS ( (cast(NULL AS varchar),cast(NULL AS varchar),cast(NULL AS varchar),cast(NULL AS varchar)) ) AS t ("id","code","code_system","display") + WHERE 1 = 0 -- ensure empty table ); -- ########################################################### @@ -139,11 +320,11 @@ WITH temp_observation AS ( o.id, o.status, o.valueString, - o.valueQuantity.value AS valuequantity_value, - o.valueQuantity.comparator AS valuequantity_comparator, - o.valueQuantity.unit AS valuequantity_unit, - o.valueQuantity.system AS valuequantity_system, - o.valueQuantity.code AS valuequantity_code, + o.valueQuantity.value AS valueQuantity_value, + o.valueQuantity.comparator AS valueQuantity_comparator, + o.valueQuantity.unit AS valueQuantity_unit, + o.valueQuantity.system AS valueQuantity_code_system, + o.valueQuantity.code AS valueQuantity_code, date_trunc('day', date(from_iso8601_timestamp(o."effectiveDateTime"))) AS effectiveDateTime_day, date_trunc('week', date(from_iso8601_timestamp(o."effectiveDateTime"))) @@ -165,8 +346,6 @@ WITH temp_observation AS ( odda.code AS dataAbsentReason_code, odda.code_system AS dataAbsentReason_code_system, odda.display AS dataAbsentReason_display, - o.referencerange, - o.valueQuantity, o.subject.reference AS subject_ref, o.encounter.reference AS encounter_ref FROM observation AS o @@ -196,8 +375,8 @@ SELECT valueCodeableConcept_display, valueQuantity_value, valueQuantity_comparator, - valueQuantity_unit, - valueQuantity_system, + valueQuantity_unit,valueQuantity_code_system AS valueQuantity_system, -- old alias + valueQuantity_code_system, valueQuantity_code, valueString, dataAbsentReason_code, @@ -211,3 +390,20 @@ WHERE effectiveDateTime_day BETWEEN date( from_iso8601_timestamp('2016-06-01') ) AND current_date; + +-- ########################################################### + + + + +CREATE TABLE core__observation_component_valuequantity AS ( + SELECT + 'x' AS id, + CAST(NULL AS BIGINT) AS row, + CAST(NULL AS DOUBLE) AS value, -- noqa: disable=L029 + 'x' AS comparator, + 'x' AS unit, + 'x' AS code_system, + 'x' AS code, + WHERE 1=0 -- empty table +); diff --git a/cumulus_library/studies/core/reference_sql/builder_patient.sql b/cumulus_library/studies/core/reference_sql/builder_patient.sql index c8b899e7..968144e2 100644 --- a/cumulus_library/studies/core/reference_sql/builder_patient.sql +++ b/cumulus_library/studies/core/reference_sql/builder_patient.sql @@ -18,7 +18,7 @@ CREATE TABLE core__patient_ext_race AS ( ext_child.ext.valuecoding.display AS race_display FROM patient AS s, - UNNEST(extension) AS ext_parent (ext), + UNNEST(s.extension) AS ext_parent (ext), UNNEST(ext_parent.ext.extension) AS ext_child (ext) WHERE ext_parent.ext.url = 'http://hl7.org/fhir/us/core/StructureDefinition/us-core-race' @@ -35,7 +35,7 @@ CREATE TABLE core__patient_ext_race AS ( ext_child.ext.valuecoding.display AS race_display FROM patient AS s, - UNNEST(extension) AS ext_parent (ext), + UNNEST(s.extension) AS ext_parent (ext), UNNEST(ext_parent.ext.extension) AS ext_child (ext) WHERE ext_parent.ext.url = 'http://hl7.org/fhir/us/core/StructureDefinition/us-core-race' @@ -52,7 +52,7 @@ CREATE TABLE core__patient_ext_race AS ( ext_child.ext.valuecoding.display AS race_display FROM patient AS s, - UNNEST(extension) AS ext_parent (ext), + UNNEST(s.extension) AS ext_parent (ext), UNNEST(ext_parent.ext.extension) AS ext_child (ext) WHERE ext_parent.ext.url = 'http://hl7.org/fhir/us/core/StructureDefinition/us-core-race' @@ -141,7 +141,7 @@ CREATE TABLE core__patient_ext_ethnicity AS ( ext_child.ext.valuecoding.display AS ethnicity_display FROM patient AS s, - UNNEST(extension) AS ext_parent (ext), + UNNEST(s.extension) AS ext_parent (ext), UNNEST(ext_parent.ext.extension) AS ext_child (ext) WHERE ext_parent.ext.url = 'http://hl7.org/fhir/us/core/StructureDefinition/us-core-ethnicity' @@ -158,7 +158,7 @@ CREATE TABLE core__patient_ext_ethnicity AS ( ext_child.ext.valuecoding.display AS ethnicity_display FROM patient AS s, - UNNEST(extension) AS ext_parent (ext), + UNNEST(s.extension) AS ext_parent (ext), UNNEST(ext_parent.ext.extension) AS ext_child (ext) WHERE ext_parent.ext.url = 'http://hl7.org/fhir/us/core/StructureDefinition/us-core-ethnicity' @@ -175,7 +175,7 @@ CREATE TABLE core__patient_ext_ethnicity AS ( ext_child.ext.valuecoding.display AS ethnicity_display FROM patient AS s, - UNNEST(extension) AS ext_parent (ext), + UNNEST(s.extension) AS ext_parent (ext), UNNEST(ext_parent.ext.extension) AS ext_child (ext) WHERE ext_parent.ext.url = 'http://hl7.org/fhir/us/core/StructureDefinition/us-core-ethnicity' diff --git a/cumulus_library/studies/discovery/code_definitions.py b/cumulus_library/studies/discovery/code_definitions.py index 9657285c..53fb1621 100644 --- a/cumulus_library/studies/discovery/code_definitions.py +++ b/cumulus_library/studies/discovery/code_definitions.py @@ -1,5 +1,6 @@ # A collection of codes & codeableConcepts to extract available codes from. +from cumulus_library.template_sql import sql_utils code_list = [ # Condition @@ -24,6 +25,7 @@ { "table_name": "encounter", "column_hierarchy": [("class", dict)], + "expected": sql_utils.CODING, }, { "table_name": "encounter", @@ -48,6 +50,7 @@ ("dischargedisposition", dict), ("coding", list), ], + "expected": {"dischargedisposition": sql_utils.CODEABLE_CONCEPT}, }, # Medication { diff --git a/cumulus_library/studies/discovery/code_detection.py b/cumulus_library/studies/discovery/code_detection.py index 2ce96c91..565639d3 100644 --- a/cumulus_library/studies/discovery/code_detection.py +++ b/cumulus_library/studies/discovery/code_detection.py @@ -1,6 +1,6 @@ """ Module for generating encounter codeableConcept table""" -from cumulus_library import base_table_builder, base_utils +from cumulus_library import base_table_builder, base_utils, databases from cumulus_library.studies.discovery import code_definitions from cumulus_library.studies.discovery.discovery_templates import discovery_templates from cumulus_library.template_sql import sql_utils @@ -9,18 +9,21 @@ class CodeDetectionBuilder(base_table_builder.BaseTableBuilder): display_text = "Selecting unique code systems..." - def _check_coding_against_db(self, code_source, schema, cursor): + def _check_coding_against_db(self, code_source, schema, cursor, parser): """selects the appropriate DB query to run""" return sql_utils.is_field_populated( schema=schema, source_table=code_source["table_name"], hierarchy=code_source["column_hierarchy"], - expected=sql_utils.CODING, + expected=code_source.get("expected"), cursor=cursor, + parser=parser, ) - def _check_codes_in_fields(self, code_sources: list[dict], schema, cursor) -> dict: + def _check_codes_in_fields( + self, code_sources: list[dict], schema, cursor, parser + ) -> dict: """checks if Coding/CodeableConcept fields are present and populated""" with base_utils.get_progress_bar() as progress: @@ -30,12 +33,19 @@ def _check_codes_in_fields(self, code_sources: list[dict], schema, cursor) -> di ) for code_source in code_sources: code_source["has_data"] = self._check_coding_against_db( - code_source, schema, cursor + code_source, schema, cursor, parser ) progress.advance(task) return code_sources - def prepare_queries(self, cursor: object, schema: str, *args, **kwargs): + def prepare_queries( + self, + cursor: databases.DatabaseCursor, + schema: str, + parser: databases.DatabaseParser = None, + *args, + **kwargs, + ): """Constructs queries related to condition codeableConcept :param cursor: A database cursor object @@ -57,7 +67,7 @@ def prepare_queries(self, cursor: object, schema: str, *args, **kwargs): for key in code_definition.keys(): code_source[key] = code_definition[key] code_sources.append(code_source) - code_sources = self._check_codes_in_fields(code_sources, schema, cursor) + code_sources = self._check_codes_in_fields(code_sources, schema, cursor, parser) query = discovery_templates.get_code_system_pairs( "discovery__code_sources", code_sources ) diff --git a/cumulus_library/template_sql/base_templates.py b/cumulus_library/template_sql/base_templates.py index 552d227b..fce8a37f 100644 --- a/cumulus_library/template_sql/base_templates.py +++ b/cumulus_library/template_sql/base_templates.py @@ -79,6 +79,9 @@ def get_codeable_concept_denormalize_query( if len(config.column_hierarchy) == 1 else config.column_hierarchy[0][0], is_array=(config.column_hierarchy[0][1] == list), + child_is_array=False + if len(config.column_hierarchy) == 1 + else config.column_hierarchy[1][1] == list, target_table=config.target_table, filter_priority=config.filter_priority, code_systems=config.code_systems, diff --git a/cumulus_library/template_sql/codeable_concept_denormalize.sql.jinja b/cumulus_library/template_sql/codeable_concept_denormalize.sql.jinja index e9e18dc4..0d511a4c 100644 --- a/cumulus_library/template_sql/codeable_concept_denormalize.sql.jinja +++ b/cumulus_library/template_sql/codeable_concept_denormalize.sql.jinja @@ -1,11 +1,48 @@ {%- import 'syntax.sql.jinja' as syntax -%} +{%- import 'unnest_utils.jinja' as unnest_utils -%} CREATE TABLE {{ target_table }} AS ( WITH + {%- if is_array %} + + flattened_rows AS ( + {{ unnest_utils.flatten(source_table, column_name, parent_field=parent_field) }} + ), + {%- set source_table = 'flattened_rows' -%} + {%- set parent_field = false %} + {%- endif %} + + {%- if child_is_array %} + + child_flattened_rows AS ( + SELECT DISTINCT + s.id, + {%- if is_array %} + s.row, -- keep the parent row number + {%- endif %} + u."{{ column_name }}" + FROM + {{ source_table }} AS s, + {%- if parent_field %} + UNNEST(s."{{ parent_field }}"."{{ column_name }}") + AS u ("{{ column_name }}") + {%- else %} + UNNEST(s."{{ column_name }}") AS u ("{{ column_name }}") + {%- endif %} + ), + {%- set source_table = 'child_flattened_rows' -%} + {%- set parent_field = false %} + {%- endif %} + {%- for system in code_systems %} system_{{ column_name }}_{{ loop.index0 }} AS ( SELECT DISTINCT s.{{ source_id }} AS id, + {%- if is_array %} + s.row, + {%- else %} + 0 AS row, + {%- endif %} {%- if filter_priority %} '{{ loop.index0 }}' AS priority, {%- endif %} @@ -14,23 +51,13 @@ CREATE TABLE {{ target_table }} AS ( u.codeable_concept.system AS code_system FROM {#- Temp workaround - to be reworked by generic DN -#} - {%- if parent_field != None %} + {%- if parent_field %} {{ source_table }} AS s, - {%- if is_array %} - UNNEST(s.{{ parent_field }}) AS parent (parent_row), - UNNEST(parent.parent_row.{{ column_name }}.coding) AS u (codeable_concept) - {%- else %} UNNEST(s.{{ parent_field }}.{{ column_name }}.coding) AS u (codeable_concept) - {%- endif %} {%- else %} {{ source_table }} AS s, - {%- if is_array %} - UNNEST(s.{{ column_name }}) AS cc (cc_row), - UNNEST(cc.cc_row.coding) AS u (codeable_concept) - {%- else %} UNNEST(s.{{ column_name }}.coding) AS u (codeable_concept) {%- endif %} - {%- endif %} {%- if filter_priority %} WHERE u.codeable_concept.system LIKE '{{ system }}' @@ -42,6 +69,7 @@ CREATE TABLE {{ target_table }} AS ( {%- for system in code_systems %} SELECT id, + row, {%- if filter_priority %} priority, {%- endif %} @@ -57,6 +85,7 @@ CREATE TABLE {{ target_table }} AS ( partitioned_table AS ( SELECT id, + row, code, code_system, display, @@ -67,12 +96,15 @@ CREATE TABLE {{ target_table }} AS ( ORDER BY priority ASC ) AS available_priority FROM union_table - GROUP BY id, priority, code_system, code, display + GROUP BY id, row, priority, code_system, code, display ORDER BY priority ASC ) SELECT id, + {%- if is_array %} + row, + {%- endif %} code, code_system, display @@ -82,6 +114,9 @@ CREATE TABLE {{ target_table }} AS ( {% else %} SELECT id, + {%- if is_array %} + row, + {%- endif %} code, code_system, display diff --git a/cumulus_library/template_sql/ctas_empty.sql.jinja b/cumulus_library/template_sql/ctas_empty.sql.jinja index 2b7163d3..edff88df 100644 --- a/cumulus_library/template_sql/ctas_empty.sql.jinja +++ b/cumulus_library/template_sql/ctas_empty.sql.jinja @@ -16,4 +16,5 @@ AS ( {{- syntax.comma_delineate(loop) }} {%- endfor -%} ) + WHERE 1 = 0 -- ensure empty table ); diff --git a/cumulus_library/template_sql/extension_denormalize.sql.jinja b/cumulus_library/template_sql/extension_denormalize.sql.jinja index e1689652..6ed53ec6 100644 --- a/cumulus_library/template_sql/extension_denormalize.sql.jinja +++ b/cumulus_library/template_sql/extension_denormalize.sql.jinja @@ -12,7 +12,7 @@ CREATE TABLE {{ target_table }} AS ( ext_child.ext.valuecoding.display AS {{ target_col_prefix }}_display FROM {{ source_table }} AS s, - UNNEST(extension) AS ext_parent (ext), + UNNEST(s.extension) AS ext_parent (ext), UNNEST(ext_parent.ext.extension) AS ext_child (ext) WHERE ext_parent.ext.url = '{{ fhir_extension }}' diff --git a/cumulus_library/template_sql/shared_macros/unnest_utils.jinja b/cumulus_library/template_sql/shared_macros/unnest_utils.jinja new file mode 100644 index 00000000..5fcf41fe --- /dev/null +++ b/cumulus_library/template_sql/shared_macros/unnest_utils.jinja @@ -0,0 +1,22 @@ +{# Flattens an array into multiple rows, with ordinality #} + +{%- macro flatten(table, field, parent_field = null, source_id = 'id') -%} + SELECT DISTINCT + t.{{ source_id }} AS id, + {#- + TODO: switch to using WITH ORDINALITY once this PR lands: + https://github.com/duckdb/duckdb/pull/9014 + Because ordering with this approach is not 100% guaranteed, + even though in practice, a SQL engine would be real rude to + give us back unnested rows in an arbitrary order. + #} + ROW_NUMBER() OVER (PARTITION BY {{ source_id }}) AS row, + r."{{ field }}" + FROM + {{ table }} AS t, + {%- if parent_field %} + UNNEST(t."{{ parent_field }}") AS parent (r) + {%- else %} + UNNEST(t."{{ field }}") AS r ("{{ field }}") + {%- endif %} +{%- endmacro -%} diff --git a/cumulus_library/template_sql/sql_utils.py b/cumulus_library/template_sql/sql_utils.py index 48ba71fb..7493f8a1 100644 --- a/cumulus_library/template_sql/sql_utils.py +++ b/cumulus_library/template_sql/sql_utils.py @@ -14,11 +14,15 @@ from cumulus_library import base_utils, databases from cumulus_library.template_sql import base_templates -# TODO: this should be reworked as part of an evenutal typesystem refactor/FHIRClient -# cutover, possibly tied to a database parser update - -CODING = ["code", "system", "display"] -CODEABLE_CONCEPT = ["coding", "code", "system", "display"] +# *** Some convenience constants for providing to validate_schema() *** +# * Only include necessary fields that we actually use. +# * If any sub-field is not present, we may ignore the parent-field. +# * Though, cumulus-fhir-support does guarantee a full Coding or Concept. +CODING = ["code", "display", "system", "userSelected", "version"] +# If you think you need CODEABLE_CONCEPT, you probably need a de-normalization table +# instead, since CodeableConcepts can contain multiple entries. +CODEABLE_CONCEPT = {"coding": CODING, "text": {}} +REFERENCE = ["reference"] @dataclass(kw_only=True) @@ -50,7 +54,7 @@ class CodeableConceptConfig(BaseConfig): column_hierarchy: list[tuple] filter_priority: bool = False code_systems: list = None - expected: list = field(default_factory=lambda: CODEABLE_CONCEPT) + expected: list | dict = field(default_factory=lambda: CODEABLE_CONCEPT) @dataclass(kw_only=True) @@ -58,7 +62,7 @@ class CodingConfig(BaseConfig): column_hierarchy: list[tuple] filter_priority: bool = False code_systems: list = None - expected: list = field(default_factory=lambda: CODING) + expected: list | dict = field(default_factory=lambda: CODING) @dataclass(kw_only=True) @@ -83,6 +87,7 @@ class ExtensionConfig(BaseConfig): def _check_data_in_fields( schema: str, cursor: databases.DatabaseCursor, + parser: databases.DatabaseParser, code_sources: list[CodeableConceptConfig], ) -> dict: """checks if CodeableConcept fields actually have data available @@ -115,6 +120,7 @@ def _check_data_in_fields( code_source.has_data = is_field_populated( schema=schema, cursor=cursor, + parser=parser, source_table=code_source.source_table, hierarchy=code_source.column_hierarchy, expected=code_source.expected, @@ -126,10 +132,11 @@ def _check_data_in_fields( def denormalize_complex_objects( schema: str, cursor: databases.DatabaseCursor, + parser: databases.DatabaseParser, code_sources: list[BaseConfig], ): queries = [] - code_sources = _check_data_in_fields(schema, cursor, code_sources) + code_sources = _check_data_in_fields(schema, cursor, parser, code_sources) for code_source in code_sources: # TODO: This method of pairing classed config objects to # specific queries should be considered temporary. This should be @@ -148,7 +155,14 @@ def denormalize_complex_objects( base_templates.get_ctas_empty_query( schema_name=schema, table_name=code_source.target_table, - table_cols=["id", "code", "code_system", "display"], + table_cols=["id", "row", "code", "code_system", "display"], + table_cols_types=[ + "varchar", + "bigint", + "varchar", + "varchar", + "varchar", + ], ) ) case CodingConfig(): @@ -168,10 +182,25 @@ def denormalize_complex_objects( return queries +def validate_schema( + cursor: databases.DatabaseCursor, + schema: str, + expected_table_cols: dict, + parser: databases.DatabaseParser, +) -> dict: + validated_schema = {} + for table, cols in expected_table_cols.items(): + query = base_templates.get_column_datatype_query(schema, table, cols.keys()) + table_schema = cursor.execute(query).fetchall() + validated_schema[table] = parser.validate_table_schema(cols, table_schema) + return validated_schema + + def is_field_populated( *, schema: str, cursor: databases.DatabaseCursor, + parser: databases.DatabaseParser, source_table: str, hierarchy: list[tuple], expected: list | None = None, @@ -191,16 +220,14 @@ def is_field_populated( if not _check_schema_if_exists( schema=schema, cursor=cursor, + parser=parser, source_table=source_table, source_col=hierarchy[0][0], expected=expected, - nested_field=hierarchy[-1][0] if len(hierarchy) > 1 else None, ): return False unnests = [] source_field = [] - last_table_alias = None - last_row_alias = None for element in hierarchy: if element[1] == list: unnests.append( @@ -233,44 +260,36 @@ def _check_schema_if_exists( *, schema: str, cursor: databases.DatabaseCursor, + parser: databases.DatabaseParser, source_table: str, source_col: str, expected: str | None = None, - nested_field: str | None = None, ) -> bool: """Validation check for a column existing, and having the expected schema :keyword schema: The schema/database name :keyword cursor: a PEP-249 compliant database cursor + :keyword parser: a database schema parser :keyword source_table: The table to query against :keyword source_col: The column to check the schema against :keyword expected: a list of elements that should be present in source_col. If none, we assume it is a CodeableConcept. :returns: a boolean indicating if the schema was found. """ - try: - query = base_templates.get_is_table_not_empty_query(source_table, source_col) - cursor.execute(query) - if cursor.fetchone() is None: - return False - - query = base_templates.get_column_datatype_query( - schema, source_table, [source_col] - ) - cursor.execute(query) - schema_str = str(cursor.fetchone()[1]) - if expected is None: - expected = CODEABLE_CONCEPT - # TODO: this naievely checks a column for: - # - containing the target field - # - containing the expected elements - # but it does not check the elements are actually associated with that field. - # This should be revisited once we've got better database parsing logic in place - if nested_field: - expected = [nested_field, *expected] - if any(x not in schema_str.lower() for x in expected): - return False - return True - - except Exception: - return False + if expected is None: + expected = CODEABLE_CONCEPT + + table_cols = {source_table: {source_col: expected}} + schema = validate_schema(cursor, schema, table_cols, parser) + + def _get_all_values(d: dict) -> list: + all_values = [] + for value in d.values(): + if isinstance(value, dict): + all_values += _get_all_values(value) + else: + all_values.append(value) + return all_values + + all_schema_values = _get_all_values(schema) + return all(all_schema_values) diff --git a/tests/conftest.py b/tests/conftest.py index 2d3cffb4..c71fddf4 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -10,11 +10,13 @@ from rich import console, table from cumulus_library.cli import StudyRunner -from cumulus_library.databases import DatabaseCursor, create_db_backend +from cumulus_library.databases import create_db_backend # Useful constants -MOCK_DATA_DIR = f"{Path(__file__).parent}/test_data/duckdb_data" +TESTS_ROOT = Path(__file__).parent +LIBRARY_ROOT = TESTS_ROOT.parent / "cumulus_library" +MOCK_DATA_DIR = f"{TESTS_ROOT}/test_data/duckdb_data" ID_PATHS = { "condition": [["id"], ["encounter", "reference"], ["subject", "reference"]], "documentreference": [ @@ -48,22 +50,6 @@ def get_sorted_table_data(cursor, table): return data, cursor.description -def modify_resource_column( - cursor: DatabaseCursor, table: str, col: str, replacement_val -): - """Allows for modifying a single table col for edge case detection - - TODO: if anything more complex than this is required for unit testing, either - create a seperate test dir directory, or consider a generator using the - existing test data as a source. - """ - df = cursor.execute(f"SELECT * from {table}").df() - df[col] = df.apply(lambda x: replacement_val, axis=1) - cursor.register(f"{table}_{col}_df", df) - cursor.execute(f"DROP VIEW {table}") - cursor.execute(f"CREATE VIEW {table} AS SELECT * from {table}_{col}_df") - - def duckdb_args(args: list, tmp_path, stats=False): """Convenience function for adding duckdb args to a CLI mock""" if stats: diff --git a/tests/core/__init__.py b/tests/core/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/test_core.py b/tests/core/test_core.py similarity index 89% rename from tests/test_core.py rename to tests/core/test_core.py index 0d4b53b7..dc9035c3 100644 --- a/tests/test_core.py +++ b/tests/core/test_core.py @@ -1,12 +1,10 @@ """unit tests for counts generation""" import datetime # noqa: F401 -from pathlib import Path import pytest import toml -from cumulus_library import cli from cumulus_library.studies.core.core_templates import core_templates from tests import conftest, testbed_utils @@ -57,23 +55,24 @@ def test_core_tables(mock_db_core, table): raise e -def test_core_count_missing_data(tmp_path, mock_db): - null_code_class = { - "id": None, - "code": None, - "display": None, - "system": "http://terminology.hl7.org/CodeSystem/v3-ActCode", - "userSelected": None, - "version": None, - } - cursor = mock_db.cursor() - conftest.modify_resource_column(cursor, "encounter", "class", null_code_class) +def test_core_count_missing_data(tmp_path): + testbed = testbed_utils.LocalTestbed(tmp_path) + for i in range(10): + row_id = str(i) + testbed.add_patient(row_id) + testbed.add_encounter( + row_id, + patient=row_id, + **{ + "status": "finished", + "class": { + # Note: no other fields here + "system": "http://terminology.hl7.org/CodeSystem/v3-ActCode", + }, + }, + ) + cursor = testbed.build() - builder = cli.StudyRunner(mock_db, f"{tmp_path}/data_path/") - builder.clean_and_build_study( - f"{Path(__file__).parent.parent}/cumulus_library/studies/core", - stats_build=False, - ) table_rows, cols = conftest.get_sorted_table_data( cursor, "core__count_encounter_month" ) @@ -104,9 +103,7 @@ def test_core_count_missing_data(tmp_path, mock_db): def test_core_counts_exported(mock_db_core): - manifest = toml.load( - f"{Path(__file__).parent.parent}/cumulus_library/studies/core/manifest.toml" - ) + manifest = toml.load(f"{conftest.LIBRARY_ROOT}/studies/core/manifest.toml") manifest["export_config"]["export_list"].remove("core__meta_version") manifest["export_config"]["export_list"].remove("core__meta_date") count_tables = ( @@ -184,10 +181,14 @@ def test_core_empty_database(tmp_path): def test_core_tiny_database(tmp_path): """Verify that we can generate core tables with some minimal data filled in""" testbed = testbed_utils.LocalTestbed(tmp_path) + # Just add bare resources, with minimal data + testbed.add_condition("ConA") testbed.add_encounter("EncA") con = testbed.build() patients = con.sql("SELECT id FROM core__patient").fetchall() assert {e[0] for e in patients} == {"A"} + conditions = con.sql("SELECT id FROM core__condition").fetchall() + assert {c[0] for c in conditions} == {"ConA"} encounters = con.sql("SELECT id FROM core__encounter").fetchall() assert {e[0] for e in encounters} == {"EncA"} diff --git a/tests/test_core_completion.py b/tests/core/test_core_completion.py similarity index 100% rename from tests/test_core_completion.py rename to tests/core/test_core_completion.py diff --git a/tests/core/test_core_observation.py b/tests/core/test_core_observation.py new file mode 100644 index 00000000..c2cbf0ea --- /dev/null +++ b/tests/core/test_core_observation.py @@ -0,0 +1,307 @@ +"""unit tests for core observation support""" + +import datetime # noqa: F401 +import json + +from tests import testbed_utils + + +def _assert_valuequantity_schema(con) -> None: + schema = con.sql( + """ + SELECT column_name, data_type + FROM information_schema.columns + WHERE table_name = 'core__observation_component_valuequantity' + """ + ).fetchall() + assert [ + ("id", "VARCHAR"), + ("row", "BIGINT"), + ("value", "DOUBLE"), + ("comparator", "VARCHAR"), + ("unit", "VARCHAR"), + ("code_system", "VARCHAR"), + ("code", "VARCHAR"), + ] == schema + + +def test_core_observation_component_low_schema(tmp_path): + """Verify that we don't explode if no components exist in the schema/data""" + testbed = testbed_utils.LocalTestbed(tmp_path) + testbed.add_observation("No Component") + con = testbed.build() # most importantly, this shouldn't blow up + # Spot check some tables (a basic one, then the custom weird valuequantity one) + rows = con.sql("SELECT id, row FROM core__observation_component_code").fetchall() + assert 0 == len(rows) + rows = con.sql( + "SELECT id FROM core__observation_component_valuequantity" + ).fetchall() + assert 0 == len(rows) + _assert_valuequantity_schema(con) + + +def test_core_observation_component_valuequantity_low_schema(tmp_path): + """Verify that we correctly handle 'value' being a float even if not present""" + testbed = testbed_utils.LocalTestbed(tmp_path) + testbed.add_observation( + "A", + component=[ + { + "valueQuantity": { + "code": "mmHg", + "system": "http://unitsofmeasure.org", + }, + } + ], + ) + con = testbed.build() # most importantly, this shouldn't blow up + rows = con.sql( + "SELECT id FROM core__observation_component_valuequantity" + ).fetchall() + assert 1 == len(rows) + _assert_valuequantity_schema(con) + + +def test_core_observation_component(tmp_path): + """Verify that we capture Observation components correctly""" + testbed = testbed_utils.LocalTestbed(tmp_path) + testbed.add_observation("No components") + testbed.add_observation( + "All fields filled in", + component=[ + { + "code": { + "coding": [ + {"display": "Hello!", "code": "hello", "system": "hi-codes"}, + ], + }, + "dataAbsentReason": { + "coding": [{"display": "D", "code": "d", "system": "letters"}], + }, + "interpretation": [ + { + "coding": [{"display": "I", "code": "i", "system": "letters"}], + } + ], + "valueCodeableConcept": { + "coding": [{"display": "V", "code": "v", "system": "letters"}], + }, + "valueQuantity": { + "code": "a-code", + "comparator": "<", + "system": "a-system", + "unit": "m", + "value": 3, + }, + }, + ], + ) + testbed.add_observation( + "Multiple components", + component=[ + { + "code": { + "coding": [ + {"code": "34", "system": "codesys"}, + {"code": "thirty-four", "system": "codesys-alpha"}, + ], + }, + "dataAbsentReason": { + "coding": [ + {"display": "gone", "code": "shrug", "system": "s"}, + {"display": "dog ate it", "code": "dog", "system": "s"}, + ], + }, + "interpretation": [ + { + "coding": [{"code": "low", "system": "high-or-low"}], + } + ], + "valueCodeableConcept": { + "coding": [{"display": "homework"}], + }, + }, + { + "code": { + "coding": [ + {"code": "42", "system": "codesys"}, + {"code": "forty-two", "system": "codesys-alpha"}, + ], + }, + "interpretation": [ + { + "coding": [ + {"display": "Good", "code": "good", "system": "quality"}, + {"display": "Pumped about this one"}, + ], + }, + {"coding": [{"code": "high", "system": "high-or-low"}]}, + ], + "valueQuantity": {"code": "here", "unit": "mmHg"}, + }, + ], + ) + con = testbed.build() + + df = con.sql( + "SELECT * FROM core__observation_component_code ORDER BY id, row, code" + ).df() + rows = json.loads(df.to_json(orient="records")) + assert [ + { + "id": "All fields filled in", + "row": 1, + "code": "hello", + "code_system": "hi-codes", + "display": "Hello!", + }, + { + "id": "Multiple components", + "row": 1, + "code": "34", + "code_system": "codesys", + "display": None, + }, + { + "id": "Multiple components", + "row": 1, + "code": "thirty-four", + "code_system": "codesys-alpha", + "display": None, + }, + { + "id": "Multiple components", + "row": 2, + "code": "42", + "code_system": "codesys", + "display": None, + }, + { + "id": "Multiple components", + "row": 2, + "code": "forty-two", + "code_system": "codesys-alpha", + "display": None, + }, + ] == rows + + df = con.sql( + "SELECT * FROM core__observation_component_dataabsentreason " + "ORDER BY id, row, code" + ).df() + rows = json.loads(df.to_json(orient="records")) + assert [ + { + "id": "All fields filled in", + "row": 1, + "code": "d", + "code_system": "letters", + "display": "D", + }, + { + "id": "Multiple components", + "row": 1, + "code": "dog", + "code_system": "s", + "display": "dog ate it", + }, + { + "id": "Multiple components", + "row": 1, + "code": "shrug", + "code_system": "s", + "display": "gone", + }, + ] == rows + + df = con.sql( + "SELECT * FROM core__observation_component_interpretation " + "ORDER BY id, row, code" + ).df() + rows = json.loads(df.to_json(orient="records")) + assert [ + { + "id": "All fields filled in", + "row": 1, + "code": "i", + "code_system": "letters", + "display": "I", + }, + { + "id": "Multiple components", + "row": 1, + "code": "low", + "code_system": "high-or-low", + "display": None, + }, + { + "id": "Multiple components", + "row": 2, + "code": "good", + "code_system": "quality", + "display": "Good", + }, + { + "id": "Multiple components", + "row": 2, + "code": "high", + "code_system": "high-or-low", + "display": None, + }, + { + "id": "Multiple components", + "row": 2, + "code": None, + "code_system": None, + "display": "Pumped about this one", + }, + ] == rows + + df = con.sql( + "SELECT * FROM core__observation_component_valuecodeableconcept " + "ORDER BY id, row, code" + ).df() + rows = json.loads(df.to_json(orient="records")) + assert [ + { + "id": "All fields filled in", + "row": 1, + "code": "v", + "code_system": "letters", + "display": "V", + }, + { + "id": "Multiple components", + "row": 1, + "code": None, + "code_system": None, + "display": "homework", + }, + ] == rows + + df = con.sql( + "SELECT * FROM core__observation_component_valuequantity " + "ORDER BY id, row, code" + ).df() + rows = json.loads(df.to_json(orient="records")) + assert [ + { + "id": "All fields filled in", + "row": 1, + "code": "a-code", + "code_system": "a-system", + "comparator": "<", + "unit": "m", + "value": 3.0, + }, + { + "id": "Multiple components", + "row": 2, + "code": "here", + "code_system": None, + "comparator": None, + "unit": "mmHg", + "value": None, + }, + ] == rows + _assert_valuequantity_schema(con) diff --git a/tests/test_athena.py b/tests/test_athena.py new file mode 100644 index 00000000..825de153 --- /dev/null +++ b/tests/test_athena.py @@ -0,0 +1,39 @@ +"""Tests for Athena database support""" + +from cumulus_library import databases + + +def test_schema_parsing(): + # A sample response for table `observation`, column `component`. + # (The original did not have any spaces.) + schema = { + "simple_field": "varchar", + "simple_row": "row(id varchar, end varchar, start varchar)", + "simple_array": "array(varchar)", + "complex": """array(row( + coding array(row(code varchar, display row(text varchar), + system varchar, userselected boolean, id varchar, + version varchar)), + text varchar, + id varchar + ))""", + } + expected = { + "simple_field": {}, + "simple_row": {"id": {}, "end": {}, "start": {}}, + "simple_array": {}, + "complex": { + "coding": { + "code": {}, + "display": {"text": {}}, + "system": {}, + "userselected": {}, + "id": {}, + "version": {}, + }, + "text": {}, + "id": {}, + }, + } + parser = databases.AthenaParser() + assert expected == parser.parse_found_schema(schema) diff --git a/tests/test_cli.py b/tests/test_cli.py index ccc120fa..ab6cb62b 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -307,7 +307,7 @@ def test_clean(mock_path, tmp_path, args, expected): # pylint: disable=unused-a @pytest.mark.parametrize( "build_args,export_args,expected_tables", [ - (["build", "-t", "core"], ["export", "-t", "core"], 49), + (["build", "-t", "core"], ["export", "-t", "core"], 57), ( # checking that a study is loaded from a child directory # of a user-defined path @@ -440,11 +440,11 @@ def test_cli_transactions(tmp_path, study, finishes, raises): query = ( db.cursor().execute("SELECT * from study_valid__lib_transactions").fetchall() ) - assert query[1][2] == "started" + assert query[0][2] == "started" if finishes: - assert query[2][2] == "finished" + assert query[1][2] == "finished" else: - assert query[2][2] == "error" + assert query[1][2] == "error" @mock.patch.dict( diff --git a/tests/test_data/core/core__condition.txt b/tests/test_data/core/core__condition.txt index eb99eca0..867ff11b 100644 --- a/tests/test_data/core/core__condition.txt +++ b/tests/test_data/core/core__condition.txt @@ -1,20 +1,20 @@ -('04b19227-b155-6b94-9e0b-f21fe61aa363', 'encounter-diagnosis', 'Encounter Diagnosis', '741062008', 'http://snomed.info/sct', 'Not in labor force (finding)', 'Patient/26baae20-c8c5-003a-ab6b-ebcc49be20db', 'Encounter/c6ec2350-43d4-abab-2e84-4d2aadb337a7', 'Condition/04b19227-b155-6b94-9e0b-f21fe61aa363', datetime.date(2018, 7, 2), datetime.date(2018, 7, 2), datetime.date(2018, 7, 1), datetime.date(2018, 1, 1), 'resolved', 'confirmed') -('12a57714-25c9-b955-bce2-5535d3f601bd', 'encounter-diagnosis', 'Encounter Diagnosis', '44465007', 'http://snomed.info/sct', 'Sprain of ankle', 'Patient/dffa62dc-8ec2-1cd6-ee75-f9156a5283fe', 'Encounter/11381dc6-0e06-da55-0735-d1e7bbf8bb35', 'Condition/12a57714-25c9-b955-bce2-5535d3f601bd', datetime.date(2018, 7, 15), datetime.date(2018, 7, 9), datetime.date(2018, 7, 1), datetime.date(2018, 1, 1), 'resolved', 'confirmed') -('16862137-0796-d625-f46a-3d0c6a04ab21', 'encounter-diagnosis', 'Encounter Diagnosis', '160903007', 'http://snomed.info/sct', 'Full-time employment (finding)', 'Patient/c1bfec36-dc2c-afc8-c767-3d35ed2bf6f0', 'Encounter/8ff1dc01-5a28-b2d8-3b42-4b7a7d539970', 'Condition/16862137-0796-d625-f46a-3d0c6a04ab21', datetime.date(2018, 7, 15), datetime.date(2018, 7, 9), datetime.date(2018, 7, 1), datetime.date(2018, 1, 1), 'resolved', 'confirmed') -('2326c8fc-857c-f55a-cabf-265b7f7f1e4d', 'encounter-diagnosis', 'Encounter Diagnosis', '368581000119106', 'http://snomed.info/sct', 'Neuropathy due to type 2 diabetes mellitus (disorder)', 'Patient/47c37c92-5932-9cfe-66be-208556780fe0', 'Encounter/b5974881-ae62-ddd6-b905-8c86c1ca9e33', 'Condition/2326c8fc-857c-f55a-cabf-265b7f7f1e4d', datetime.date(2018, 6, 25), datetime.date(2018, 6, 25), datetime.date(2018, 6, 1), datetime.date(2018, 1, 1), 'active', 'confirmed') -('2902cab2-9b4c-0914-3770-375c1922b2be', 'encounter-diagnosis', 'Encounter Diagnosis', '422650009', 'http://snomed.info/sct', 'Social isolation (finding)', 'Patient/24906e2c-e556-71dc-23d9-3e1d5fb08986', 'Encounter/1154d05c-8727-9373-4224-25b9fdba9ab3', 'Condition/2902cab2-9b4c-0914-3770-375c1922b2be', datetime.date(2018, 6, 14), datetime.date(2018, 6, 11), datetime.date(2018, 6, 1), datetime.date(2018, 1, 1), 'resolved', 'confirmed') -('37d6e6ce-f2fe-47be-5d9b-d071ad17d6d9', 'encounter-diagnosis', 'Encounter Diagnosis', '195662009', 'http://snomed.info/sct', 'Acute viral pharyngitis (disorder)', 'Patient/19158de4-66a2-f70f-e3bf-4396b312c8f1', 'Encounter/ed151e04-3dd6-8cb7-a3e5-777c8a8667f1', 'Condition/37d6e6ce-f2fe-47be-5d9b-d071ad17d6d9', datetime.date(2018, 6, 6), datetime.date(2018, 6, 4), datetime.date(2018, 6, 1), datetime.date(2018, 1, 1), 'resolved', 'confirmed') -('5f42b886-36a7-811e-366e-1e35de8a1dd3', 'encounter-diagnosis', 'Encounter Diagnosis', '444814009', 'http://snomed.info/sct', 'Viral sinusitis (disorder)', 'Patient/f9399f0d-5401-09f3-d4ff-89b1aa51b9c8', 'Encounter/6a952afd-3be5-e27e-9e05-5a1e085e34d0', 'Condition/5f42b886-36a7-811e-366e-1e35de8a1dd3', datetime.date(2018, 7, 21), datetime.date(2018, 7, 16), datetime.date(2018, 7, 1), datetime.date(2018, 1, 1), 'resolved', 'confirmed') -('670d9a8e-b153-71f1-e691-f9883ad59660', 'encounter-diagnosis', 'Encounter Diagnosis', '160903007', 'http://snomed.info/sct', 'Full-time employment (finding)', 'Patient/0b052286-9534-99a8-8d5e-06c2c04a7df7', 'Encounter/e5dabcb6-1d7a-7467-dbba-b864d0d5f5b0', 'Condition/670d9a8e-b153-71f1-e691-f9883ad59660', datetime.date(2018, 7, 28), datetime.date(2018, 7, 23), datetime.date(2018, 7, 1), datetime.date(2018, 1, 1), 'resolved', 'confirmed') -('8ba53b28-7692-27db-95ee-f54c43d51ada', 'encounter-diagnosis', 'Encounter Diagnosis', '422650009', 'http://snomed.info/sct', 'Social isolation (finding)', 'Patient/26baae20-c8c5-003a-ab6b-ebcc49be20db', 'Encounter/c6ec2350-43d4-abab-2e84-4d2aadb337a7', 'Condition/8ba53b28-7692-27db-95ee-f54c43d51ada', datetime.date(2018, 7, 2), datetime.date(2018, 7, 2), datetime.date(2018, 7, 1), datetime.date(2018, 1, 1), 'resolved', 'confirmed') -('9051f537-e64c-cf0d-381b-7d436bb5ad31', 'encounter-diagnosis', 'Encounter Diagnosis', '160903007', 'http://snomed.info/sct', 'Full-time employment (finding)', 'Patient/17fde357-dcc9-af8b-a8d3-4bd213afeb22', 'Encounter/32d0ae2d-1be8-9e90-a4da-4c222abd88a9', 'Condition/9051f537-e64c-cf0d-381b-7d436bb5ad31', datetime.date(2018, 7, 2), datetime.date(2018, 7, 2), datetime.date(2018, 7, 1), datetime.date(2018, 1, 1), 'resolved', 'confirmed') -('96b8e886-7711-a5c6-5d11-b885815cd605', 'encounter-diagnosis', 'Encounter Diagnosis', '33737001', 'http://snomed.info/sct', 'Fracture of rib', 'Patient/ad3ed58a-5645-af0a-eeca-ab543123a8aa', 'Encounter/03e34b19-2889-b828-792d-2a83400c55be', 'Condition/96b8e886-7711-a5c6-5d11-b885815cd605', datetime.date(2018, 7, 19), datetime.date(2018, 7, 16), datetime.date(2018, 7, 1), datetime.date(2018, 1, 1), 'resolved', 'confirmed') -('9da05ddf-80b1-649e-84a0-716fadbc3a18', 'encounter-diagnosis', 'Encounter Diagnosis', '160903007', 'http://snomed.info/sct', 'Full-time employment (finding)', 'Patient/267fc42d-cd9e-8527-1f9e-887fe7776147', 'Encounter/4c4d0730-201f-5b75-c657-8d0de09cc28f', 'Condition/9da05ddf-80b1-649e-84a0-716fadbc3a18', datetime.date(2018, 6, 14), datetime.date(2018, 6, 11), datetime.date(2018, 6, 1), datetime.date(2018, 1, 1), 'resolved', 'confirmed') -('a68c48f9-294f-a8a9-254f-0c507408a7b3', 'encounter-diagnosis', 'Encounter Diagnosis', '73595000', 'http://snomed.info/sct', 'Stress (finding)', 'Patient/267fc42d-cd9e-8527-1f9e-887fe7776147', 'Encounter/4c4d0730-201f-5b75-c657-8d0de09cc28f', 'Condition/a68c48f9-294f-a8a9-254f-0c507408a7b3', datetime.date(2018, 6, 14), datetime.date(2018, 6, 11), datetime.date(2018, 6, 1), datetime.date(2018, 1, 1), 'resolved', 'confirmed') -('b6f8f751-fcdc-1cb8-a1e9-58b44e06e7f5', 'encounter-diagnosis', 'Encounter Diagnosis', '73595000', 'http://snomed.info/sct', 'Stress (finding)', 'Patient/8877ef1f-7cd7-3242-d7f0-73cf3f7165f4', 'Encounter/299b6495-3fe7-8db3-c494-6e1ce8b7986d', 'Condition/b6f8f751-fcdc-1cb8-a1e9-58b44e06e7f5', datetime.date(2018, 6, 2), datetime.date(2018, 5, 28), datetime.date(2018, 6, 1), datetime.date(2018, 1, 1), 'resolved', 'confirmed') -('c38b2f78-33ab-e4a3-2fa4-70bcb3f5f2aa', 'encounter-diagnosis', 'Encounter Diagnosis', '160903007', 'http://snomed.info/sct', 'Full-time employment (finding)', 'Patient/3cf7af45-2bee-aa9c-d524-40b487149d60', 'Encounter/d2782687-6885-037c-957d-579fbd681d2a', 'Condition/c38b2f78-33ab-e4a3-2fa4-70bcb3f5f2aa', datetime.date(2018, 6, 13), datetime.date(2018, 6, 11), datetime.date(2018, 6, 1), datetime.date(2018, 1, 1), 'resolved', 'confirmed') -('cd47a2f1-0790-a0bc-dc21-803a35b94f60', 'encounter-diagnosis', 'Encounter Diagnosis', '10509002', 'http://snomed.info/sct', 'Acute bronchitis (disorder)', 'Patient/7f941bcc-e7b2-99e1-585f-129d0ef1c13d', 'Encounter/65f8fdca-a949-80a0-8072-094e9aaee474', 'Condition/cd47a2f1-0790-a0bc-dc21-803a35b94f60', datetime.date(2018, 6, 17), datetime.date(2018, 6, 11), datetime.date(2018, 6, 1), datetime.date(2018, 1, 1), 'resolved', 'confirmed') -('db40e065-6d20-7d2b-c39f-1edd8cbf5f32', 'encounter-diagnosis', 'Encounter Diagnosis', '424393004', 'http://snomed.info/sct', 'Reports of violence in the environment (finding)', 'Patient/3cf7af45-2bee-aa9c-d524-40b487149d60', 'Encounter/d2782687-6885-037c-957d-579fbd681d2a', 'Condition/db40e065-6d20-7d2b-c39f-1edd8cbf5f32', datetime.date(2018, 6, 13), datetime.date(2018, 6, 11), datetime.date(2018, 6, 1), datetime.date(2018, 1, 1), 'resolved', 'confirmed') -('e42a4ee4-3751-0a77-2f0e-ef23efe809e4', 'encounter-diagnosis', 'Encounter Diagnosis', '160903007', 'http://snomed.info/sct', 'Full-time employment (finding)', 'Patient/24906e2c-e556-71dc-23d9-3e1d5fb08986', 'Encounter/1154d05c-8727-9373-4224-25b9fdba9ab3', 'Condition/e42a4ee4-3751-0a77-2f0e-ef23efe809e4', datetime.date(2018, 6, 14), datetime.date(2018, 6, 11), datetime.date(2018, 6, 1), datetime.date(2018, 1, 1), 'resolved', 'confirmed') -('f1d8fe31-eafd-ab02-988c-5f9af674c005', 'encounter-diagnosis', 'Encounter Diagnosis', '160903007', 'http://snomed.info/sct', 'Full-time employment (finding)', 'Patient/8877ef1f-7cd7-3242-d7f0-73cf3f7165f4', 'Encounter/299b6495-3fe7-8db3-c494-6e1ce8b7986d', 'Condition/f1d8fe31-eafd-ab02-988c-5f9af674c005', datetime.date(2018, 6, 2), datetime.date(2018, 5, 28), datetime.date(2018, 6, 1), datetime.date(2018, 1, 1), 'resolved', 'confirmed') -('f6183aaf-47b5-0574-01ae-dd38641a98f0', 'encounter-diagnosis', 'Encounter Diagnosis', '160903007', 'http://snomed.info/sct', 'Full-time employment (finding)', 'Patient/a5b171a7-9b28-20e7-86a7-936ecbf55f36', 'Encounter/c4605953-3103-ede6-e0c0-e0588e6f019e', 'Condition/f6183aaf-47b5-0574-01ae-dd38641a98f0', datetime.date(2018, 7, 27), datetime.date(2018, 7, 23), datetime.date(2018, 7, 1), datetime.date(2018, 1, 1), 'resolved', 'confirmed') +('04b19227-b155-6b94-9e0b-f21fe61aa363', 'encounter-diagnosis', 'http://terminology.hl7.org/CodeSystem/condition-category', 'Encounter Diagnosis', '741062008', 'http://snomed.info/sct', 'Not in labor force (finding)', 'Patient/26baae20-c8c5-003a-ab6b-ebcc49be20db', 'Encounter/c6ec2350-43d4-abab-2e84-4d2aadb337a7', 'Condition/04b19227-b155-6b94-9e0b-f21fe61aa363', datetime.date(2018, 7, 2), datetime.date(2018, 7, 2), datetime.date(2018, 7, 1), datetime.date(2018, 1, 1), 'resolved', 'confirmed') +('12a57714-25c9-b955-bce2-5535d3f601bd', 'encounter-diagnosis', 'http://terminology.hl7.org/CodeSystem/condition-category', 'Encounter Diagnosis', '44465007', 'http://snomed.info/sct', 'Sprain of ankle', 'Patient/dffa62dc-8ec2-1cd6-ee75-f9156a5283fe', 'Encounter/11381dc6-0e06-da55-0735-d1e7bbf8bb35', 'Condition/12a57714-25c9-b955-bce2-5535d3f601bd', datetime.date(2018, 7, 15), datetime.date(2018, 7, 9), datetime.date(2018, 7, 1), datetime.date(2018, 1, 1), 'resolved', 'confirmed') +('16862137-0796-d625-f46a-3d0c6a04ab21', 'encounter-diagnosis', 'http://terminology.hl7.org/CodeSystem/condition-category', 'Encounter Diagnosis', '160903007', 'http://snomed.info/sct', 'Full-time employment (finding)', 'Patient/c1bfec36-dc2c-afc8-c767-3d35ed2bf6f0', 'Encounter/8ff1dc01-5a28-b2d8-3b42-4b7a7d539970', 'Condition/16862137-0796-d625-f46a-3d0c6a04ab21', datetime.date(2018, 7, 15), datetime.date(2018, 7, 9), datetime.date(2018, 7, 1), datetime.date(2018, 1, 1), 'resolved', 'confirmed') +('2326c8fc-857c-f55a-cabf-265b7f7f1e4d', 'encounter-diagnosis', 'http://terminology.hl7.org/CodeSystem/condition-category', 'Encounter Diagnosis', '368581000119106', 'http://snomed.info/sct', 'Neuropathy due to type 2 diabetes mellitus (disorder)', 'Patient/47c37c92-5932-9cfe-66be-208556780fe0', 'Encounter/b5974881-ae62-ddd6-b905-8c86c1ca9e33', 'Condition/2326c8fc-857c-f55a-cabf-265b7f7f1e4d', datetime.date(2018, 6, 25), datetime.date(2018, 6, 25), datetime.date(2018, 6, 1), datetime.date(2018, 1, 1), 'active', 'confirmed') +('2902cab2-9b4c-0914-3770-375c1922b2be', 'encounter-diagnosis', 'http://terminology.hl7.org/CodeSystem/condition-category', 'Encounter Diagnosis', '422650009', 'http://snomed.info/sct', 'Social isolation (finding)', 'Patient/24906e2c-e556-71dc-23d9-3e1d5fb08986', 'Encounter/1154d05c-8727-9373-4224-25b9fdba9ab3', 'Condition/2902cab2-9b4c-0914-3770-375c1922b2be', datetime.date(2018, 6, 14), datetime.date(2018, 6, 11), datetime.date(2018, 6, 1), datetime.date(2018, 1, 1), 'resolved', 'confirmed') +('37d6e6ce-f2fe-47be-5d9b-d071ad17d6d9', 'encounter-diagnosis', 'http://terminology.hl7.org/CodeSystem/condition-category', 'Encounter Diagnosis', '195662009', 'http://snomed.info/sct', 'Acute viral pharyngitis (disorder)', 'Patient/19158de4-66a2-f70f-e3bf-4396b312c8f1', 'Encounter/ed151e04-3dd6-8cb7-a3e5-777c8a8667f1', 'Condition/37d6e6ce-f2fe-47be-5d9b-d071ad17d6d9', datetime.date(2018, 6, 6), datetime.date(2018, 6, 4), datetime.date(2018, 6, 1), datetime.date(2018, 1, 1), 'resolved', 'confirmed') +('5f42b886-36a7-811e-366e-1e35de8a1dd3', 'encounter-diagnosis', 'http://terminology.hl7.org/CodeSystem/condition-category', 'Encounter Diagnosis', '444814009', 'http://snomed.info/sct', 'Viral sinusitis (disorder)', 'Patient/f9399f0d-5401-09f3-d4ff-89b1aa51b9c8', 'Encounter/6a952afd-3be5-e27e-9e05-5a1e085e34d0', 'Condition/5f42b886-36a7-811e-366e-1e35de8a1dd3', datetime.date(2018, 7, 21), datetime.date(2018, 7, 16), datetime.date(2018, 7, 1), datetime.date(2018, 1, 1), 'resolved', 'confirmed') +('670d9a8e-b153-71f1-e691-f9883ad59660', 'encounter-diagnosis', 'http://terminology.hl7.org/CodeSystem/condition-category', 'Encounter Diagnosis', '160903007', 'http://snomed.info/sct', 'Full-time employment (finding)', 'Patient/0b052286-9534-99a8-8d5e-06c2c04a7df7', 'Encounter/e5dabcb6-1d7a-7467-dbba-b864d0d5f5b0', 'Condition/670d9a8e-b153-71f1-e691-f9883ad59660', datetime.date(2018, 7, 28), datetime.date(2018, 7, 23), datetime.date(2018, 7, 1), datetime.date(2018, 1, 1), 'resolved', 'confirmed') +('8ba53b28-7692-27db-95ee-f54c43d51ada', 'encounter-diagnosis', 'http://terminology.hl7.org/CodeSystem/condition-category', 'Encounter Diagnosis', '422650009', 'http://snomed.info/sct', 'Social isolation (finding)', 'Patient/26baae20-c8c5-003a-ab6b-ebcc49be20db', 'Encounter/c6ec2350-43d4-abab-2e84-4d2aadb337a7', 'Condition/8ba53b28-7692-27db-95ee-f54c43d51ada', datetime.date(2018, 7, 2), datetime.date(2018, 7, 2), datetime.date(2018, 7, 1), datetime.date(2018, 1, 1), 'resolved', 'confirmed') +('9051f537-e64c-cf0d-381b-7d436bb5ad31', 'encounter-diagnosis', 'http://terminology.hl7.org/CodeSystem/condition-category', 'Encounter Diagnosis', '160903007', 'http://snomed.info/sct', 'Full-time employment (finding)', 'Patient/17fde357-dcc9-af8b-a8d3-4bd213afeb22', 'Encounter/32d0ae2d-1be8-9e90-a4da-4c222abd88a9', 'Condition/9051f537-e64c-cf0d-381b-7d436bb5ad31', datetime.date(2018, 7, 2), datetime.date(2018, 7, 2), datetime.date(2018, 7, 1), datetime.date(2018, 1, 1), 'resolved', 'confirmed') +('96b8e886-7711-a5c6-5d11-b885815cd605', 'encounter-diagnosis', 'http://terminology.hl7.org/CodeSystem/condition-category', 'Encounter Diagnosis', '33737001', 'http://snomed.info/sct', 'Fracture of rib', 'Patient/ad3ed58a-5645-af0a-eeca-ab543123a8aa', 'Encounter/03e34b19-2889-b828-792d-2a83400c55be', 'Condition/96b8e886-7711-a5c6-5d11-b885815cd605', datetime.date(2018, 7, 19), datetime.date(2018, 7, 16), datetime.date(2018, 7, 1), datetime.date(2018, 1, 1), 'resolved', 'confirmed') +('9da05ddf-80b1-649e-84a0-716fadbc3a18', 'encounter-diagnosis', 'http://terminology.hl7.org/CodeSystem/condition-category', 'Encounter Diagnosis', '160903007', 'http://snomed.info/sct', 'Full-time employment (finding)', 'Patient/267fc42d-cd9e-8527-1f9e-887fe7776147', 'Encounter/4c4d0730-201f-5b75-c657-8d0de09cc28f', 'Condition/9da05ddf-80b1-649e-84a0-716fadbc3a18', datetime.date(2018, 6, 14), datetime.date(2018, 6, 11), datetime.date(2018, 6, 1), datetime.date(2018, 1, 1), 'resolved', 'confirmed') +('a68c48f9-294f-a8a9-254f-0c507408a7b3', 'encounter-diagnosis', 'http://terminology.hl7.org/CodeSystem/condition-category', 'Encounter Diagnosis', '73595000', 'http://snomed.info/sct', 'Stress (finding)', 'Patient/267fc42d-cd9e-8527-1f9e-887fe7776147', 'Encounter/4c4d0730-201f-5b75-c657-8d0de09cc28f', 'Condition/a68c48f9-294f-a8a9-254f-0c507408a7b3', datetime.date(2018, 6, 14), datetime.date(2018, 6, 11), datetime.date(2018, 6, 1), datetime.date(2018, 1, 1), 'resolved', 'confirmed') +('b6f8f751-fcdc-1cb8-a1e9-58b44e06e7f5', 'encounter-diagnosis', 'http://terminology.hl7.org/CodeSystem/condition-category', 'Encounter Diagnosis', '73595000', 'http://snomed.info/sct', 'Stress (finding)', 'Patient/8877ef1f-7cd7-3242-d7f0-73cf3f7165f4', 'Encounter/299b6495-3fe7-8db3-c494-6e1ce8b7986d', 'Condition/b6f8f751-fcdc-1cb8-a1e9-58b44e06e7f5', datetime.date(2018, 6, 2), datetime.date(2018, 5, 28), datetime.date(2018, 6, 1), datetime.date(2018, 1, 1), 'resolved', 'confirmed') +('c38b2f78-33ab-e4a3-2fa4-70bcb3f5f2aa', 'encounter-diagnosis', 'http://terminology.hl7.org/CodeSystem/condition-category', 'Encounter Diagnosis', '160903007', 'http://snomed.info/sct', 'Full-time employment (finding)', 'Patient/3cf7af45-2bee-aa9c-d524-40b487149d60', 'Encounter/d2782687-6885-037c-957d-579fbd681d2a', 'Condition/c38b2f78-33ab-e4a3-2fa4-70bcb3f5f2aa', datetime.date(2018, 6, 13), datetime.date(2018, 6, 11), datetime.date(2018, 6, 1), datetime.date(2018, 1, 1), 'resolved', 'confirmed') +('cd47a2f1-0790-a0bc-dc21-803a35b94f60', 'encounter-diagnosis', 'http://terminology.hl7.org/CodeSystem/condition-category', 'Encounter Diagnosis', '10509002', 'http://snomed.info/sct', 'Acute bronchitis (disorder)', 'Patient/7f941bcc-e7b2-99e1-585f-129d0ef1c13d', 'Encounter/65f8fdca-a949-80a0-8072-094e9aaee474', 'Condition/cd47a2f1-0790-a0bc-dc21-803a35b94f60', datetime.date(2018, 6, 17), datetime.date(2018, 6, 11), datetime.date(2018, 6, 1), datetime.date(2018, 1, 1), 'resolved', 'confirmed') +('db40e065-6d20-7d2b-c39f-1edd8cbf5f32', 'encounter-diagnosis', 'http://terminology.hl7.org/CodeSystem/condition-category', 'Encounter Diagnosis', '424393004', 'http://snomed.info/sct', 'Reports of violence in the environment (finding)', 'Patient/3cf7af45-2bee-aa9c-d524-40b487149d60', 'Encounter/d2782687-6885-037c-957d-579fbd681d2a', 'Condition/db40e065-6d20-7d2b-c39f-1edd8cbf5f32', datetime.date(2018, 6, 13), datetime.date(2018, 6, 11), datetime.date(2018, 6, 1), datetime.date(2018, 1, 1), 'resolved', 'confirmed') +('e42a4ee4-3751-0a77-2f0e-ef23efe809e4', 'encounter-diagnosis', 'http://terminology.hl7.org/CodeSystem/condition-category', 'Encounter Diagnosis', '160903007', 'http://snomed.info/sct', 'Full-time employment (finding)', 'Patient/24906e2c-e556-71dc-23d9-3e1d5fb08986', 'Encounter/1154d05c-8727-9373-4224-25b9fdba9ab3', 'Condition/e42a4ee4-3751-0a77-2f0e-ef23efe809e4', datetime.date(2018, 6, 14), datetime.date(2018, 6, 11), datetime.date(2018, 6, 1), datetime.date(2018, 1, 1), 'resolved', 'confirmed') +('f1d8fe31-eafd-ab02-988c-5f9af674c005', 'encounter-diagnosis', 'http://terminology.hl7.org/CodeSystem/condition-category', 'Encounter Diagnosis', '160903007', 'http://snomed.info/sct', 'Full-time employment (finding)', 'Patient/8877ef1f-7cd7-3242-d7f0-73cf3f7165f4', 'Encounter/299b6495-3fe7-8db3-c494-6e1ce8b7986d', 'Condition/f1d8fe31-eafd-ab02-988c-5f9af674c005', datetime.date(2018, 6, 2), datetime.date(2018, 5, 28), datetime.date(2018, 6, 1), datetime.date(2018, 1, 1), 'resolved', 'confirmed') +('f6183aaf-47b5-0574-01ae-dd38641a98f0', 'encounter-diagnosis', 'http://terminology.hl7.org/CodeSystem/condition-category', 'Encounter Diagnosis', '160903007', 'http://snomed.info/sct', 'Full-time employment (finding)', 'Patient/a5b171a7-9b28-20e7-86a7-936ecbf55f36', 'Encounter/c4605953-3103-ede6-e0c0-e0588e6f019e', 'Condition/f6183aaf-47b5-0574-01ae-dd38641a98f0', datetime.date(2018, 7, 27), datetime.date(2018, 7, 23), datetime.date(2018, 7, 1), datetime.date(2018, 1, 1), 'resolved', 'confirmed') diff --git a/tests/test_data/core/core__count_encounter_month_missing_data.txt b/tests/test_data/core/core__count_encounter_month_missing_data.txt index 49bdbe0b..a9e8a5c9 100644 --- a/tests/test_data/core/core__count_encounter_month_missing_data.txt +++ b/tests/test_data/core/core__count_encounter_month_missing_data.txt @@ -1,64 +1,64 @@ -(10, '2018-07-01', 'cumulus__none', None, 'male', 'white', 'not hispanic or latino') -(10, '2018-07-01', 'cumulus__none', None, 'male', None, 'not hispanic or latino') -(10, '2018-07-01', None, None, 'male', 'white', 'not hispanic or latino') -(10, '2018-07-01', None, None, 'male', None, 'not hispanic or latino') -(12, '2018-06-01', 'cumulus__none', None, 'female', 'white', 'not hispanic or latino') -(12, '2018-06-01', None, None, 'female', 'white', 'not hispanic or latino') -(12, '2018-07-01', 'cumulus__none', None, 'male', 'white', None) -(12, '2018-07-01', 'cumulus__none', None, 'male', None, None) -(12, '2018-07-01', None, None, 'male', 'white', None) -(12, '2018-07-01', None, None, 'male', None, None) -(13, '2018-06-01', 'cumulus__none', None, 'female', None, 'not hispanic or latino') -(13, '2018-06-01', None, None, 'female', None, 'not hispanic or latino') -(14, '2018-06-01', 'cumulus__none', None, 'female', 'white', None) -(14, '2018-06-01', None, None, 'female', 'white', None) -(14, '2018-07-01', 'cumulus__none', None, 'female', 'white', None) -(14, '2018-07-01', 'cumulus__none', None, 'female', 'white', 'not hispanic or latino') -(14, '2018-07-01', 'cumulus__none', None, 'female', None, 'not hispanic or latino') -(14, '2018-07-01', 'cumulus__none', None, 'female', None, None) -(14, '2018-07-01', None, None, 'female', 'white', None) -(14, '2018-07-01', None, None, 'female', 'white', 'not hispanic or latino') -(14, '2018-07-01', None, None, 'female', None, None) -(14, '2018-07-01', None, None, 'female', None, 'not hispanic or latino') -(15, '2018-06-01', 'cumulus__none', None, 'female', None, None) -(15, '2018-06-01', None, None, 'female', None, None) -(17, None, 'cumulus__none', None, 'male', 'white', 'not hispanic or latino') -(17, None, None, None, 'male', 'white', 'not hispanic or latino') -(18, None, 'cumulus__none', None, 'male', None, 'not hispanic or latino') -(18, None, None, None, 'male', None, 'not hispanic or latino') -(19, '2018-06-01', 'cumulus__none', None, None, 'white', 'not hispanic or latino') -(19, '2018-06-01', None, None, None, 'white', 'not hispanic or latino') -(19, None, 'cumulus__none', None, 'male', 'white', None) -(19, None, None, None, 'male', 'white', None) -(21, '2018-06-01', 'cumulus__none', None, None, 'white', None) -(21, '2018-06-01', 'cumulus__none', None, None, None, 'not hispanic or latino') -(21, '2018-06-01', None, None, None, 'white', None) -(21, '2018-06-01', None, None, None, None, 'not hispanic or latino') -(21, None, 'cumulus__none', None, 'male', None, None) -(21, None, None, None, 'male', None, None) -(24, '2018-06-01', 'cumulus__none', None, None, None, None) -(24, '2018-06-01', None, None, None, None, None) -(24, '2018-07-01', 'cumulus__none', None, None, 'white', 'not hispanic or latino') -(24, '2018-07-01', 'cumulus__none', None, None, None, 'not hispanic or latino') -(24, '2018-07-01', None, None, None, 'white', 'not hispanic or latino') -(24, '2018-07-01', None, None, None, None, 'not hispanic or latino') -(26, '2018-07-01', 'cumulus__none', None, None, 'white', None) -(26, '2018-07-01', 'cumulus__none', None, None, None, None) -(26, '2018-07-01', None, None, None, 'white', None) -(26, '2018-07-01', None, None, None, None, None) -(26, None, 'cumulus__none', None, 'female', 'white', 'not hispanic or latino') -(26, None, None, None, 'female', 'white', 'not hispanic or latino') -(27, None, 'cumulus__none', None, 'female', None, 'not hispanic or latino') -(27, None, None, None, 'female', None, 'not hispanic or latino') -(28, None, 'cumulus__none', None, 'female', 'white', None) -(28, None, None, None, 'female', 'white', None) -(29, None, 'cumulus__none', None, 'female', None, None) -(29, None, None, None, 'female', None, None) -(43, None, 'cumulus__none', None, None, 'white', 'not hispanic or latino') -(43, None, None, None, None, 'white', 'not hispanic or latino') -(45, None, 'cumulus__none', None, None, None, 'not hispanic or latino') -(45, None, None, None, None, None, 'not hispanic or latino') -(47, None, 'cumulus__none', None, None, 'white', None) -(47, None, None, None, None, 'white', None) -(50, None, 'cumulus__none', None, None, None, None) -(50, None, None, None, None, None, None) +(10, '2020-01-01', 'cumulus__none', '20', 'unknown', 'unknown', None) +(10, '2020-01-01', 'cumulus__none', '20', 'unknown', 'unknown', 'unknown') +(10, '2020-01-01', 'cumulus__none', '20', 'unknown', None, None) +(10, '2020-01-01', 'cumulus__none', '20', 'unknown', None, 'unknown') +(10, '2020-01-01', 'cumulus__none', '20', None, 'unknown', None) +(10, '2020-01-01', 'cumulus__none', '20', None, 'unknown', 'unknown') +(10, '2020-01-01', 'cumulus__none', '20', None, None, None) +(10, '2020-01-01', 'cumulus__none', '20', None, None, 'unknown') +(10, '2020-01-01', 'cumulus__none', None, 'unknown', 'unknown', None) +(10, '2020-01-01', 'cumulus__none', None, 'unknown', 'unknown', 'unknown') +(10, '2020-01-01', 'cumulus__none', None, 'unknown', None, None) +(10, '2020-01-01', 'cumulus__none', None, 'unknown', None, 'unknown') +(10, '2020-01-01', 'cumulus__none', None, None, 'unknown', None) +(10, '2020-01-01', 'cumulus__none', None, None, 'unknown', 'unknown') +(10, '2020-01-01', 'cumulus__none', None, None, None, None) +(10, '2020-01-01', 'cumulus__none', None, None, None, 'unknown') +(10, '2020-01-01', None, '20', 'unknown', 'unknown', None) +(10, '2020-01-01', None, '20', 'unknown', 'unknown', 'unknown') +(10, '2020-01-01', None, '20', 'unknown', None, None) +(10, '2020-01-01', None, '20', 'unknown', None, 'unknown') +(10, '2020-01-01', None, '20', None, 'unknown', None) +(10, '2020-01-01', None, '20', None, 'unknown', 'unknown') +(10, '2020-01-01', None, '20', None, None, 'unknown') +(10, '2020-01-01', None, '20', None, None, None) +(10, '2020-01-01', None, None, 'unknown', 'unknown', None) +(10, '2020-01-01', None, None, 'unknown', 'unknown', 'unknown') +(10, '2020-01-01', None, None, 'unknown', None, None) +(10, '2020-01-01', None, None, 'unknown', None, 'unknown') +(10, '2020-01-01', None, None, None, 'unknown', None) +(10, '2020-01-01', None, None, None, 'unknown', 'unknown') +(10, '2020-01-01', None, None, None, None, None) +(10, '2020-01-01', None, None, None, None, 'unknown') +(10, None, 'cumulus__none', '20', 'unknown', 'unknown', None) +(10, None, 'cumulus__none', '20', 'unknown', 'unknown', 'unknown') +(10, None, 'cumulus__none', '20', 'unknown', None, None) +(10, None, 'cumulus__none', '20', 'unknown', None, 'unknown') +(10, None, 'cumulus__none', '20', None, 'unknown', None) +(10, None, 'cumulus__none', '20', None, 'unknown', 'unknown') +(10, None, 'cumulus__none', '20', None, None, None) +(10, None, 'cumulus__none', '20', None, None, 'unknown') +(10, None, 'cumulus__none', None, 'unknown', 'unknown', None) +(10, None, 'cumulus__none', None, 'unknown', 'unknown', 'unknown') +(10, None, 'cumulus__none', None, 'unknown', None, None) +(10, None, 'cumulus__none', None, 'unknown', None, 'unknown') +(10, None, 'cumulus__none', None, None, 'unknown', None) +(10, None, 'cumulus__none', None, None, 'unknown', 'unknown') +(10, None, 'cumulus__none', None, None, None, None) +(10, None, 'cumulus__none', None, None, None, 'unknown') +(10, None, None, '20', 'unknown', 'unknown', None) +(10, None, None, '20', 'unknown', 'unknown', 'unknown') +(10, None, None, '20', 'unknown', None, 'unknown') +(10, None, None, '20', 'unknown', None, None) +(10, None, None, '20', None, 'unknown', None) +(10, None, None, '20', None, 'unknown', 'unknown') +(10, None, None, '20', None, None, 'unknown') +(10, None, None, '20', None, None, None) +(10, None, None, None, 'unknown', 'unknown', None) +(10, None, None, None, 'unknown', 'unknown', 'unknown') +(10, None, None, None, 'unknown', None, 'unknown') +(10, None, None, None, 'unknown', None, None) +(10, None, None, None, None, 'unknown', 'unknown') +(10, None, None, None, None, 'unknown', None) +(10, None, None, None, None, None, 'unknown') +(10, None, None, None, None, None, None) diff --git a/tests/test_data/core/core__documentreference.txt b/tests/test_data/core/core__documentreference.txt index 1b65ef5e..2cf4271a 100644 --- a/tests/test_data/core/core__documentreference.txt +++ b/tests/test_data/core/core__documentreference.txt @@ -1,102 +1,102 @@ -('351ea353-4dc6-b0a8-2a70-0e5478e8171e', 'current', '34111-5', 'http://loinc.org', 'Emergency department note', None, None, None, datetime.date(2018, 6, 15), datetime.date(2018, 6, 11), datetime.date(2018, 6, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/cb8c0665-30ee-479c-8994-d29f1a6848b0', 'Encounter/1d679c3a-2765-5e13-e2a3-4bd76a898fc6', 'DocumentReference/351ea353-4dc6-b0a8-2a70-0e5478e8171e') -('351ea353-4dc6-b0a8-2a70-0e5478e8171e', 'current', '51847-2', 'http://loinc.org', 'Evaluation + Plan note', None, None, None, datetime.date(2018, 6, 15), datetime.date(2018, 6, 11), datetime.date(2018, 6, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/cb8c0665-30ee-479c-8994-d29f1a6848b0', 'Encounter/1d679c3a-2765-5e13-e2a3-4bd76a898fc6', 'DocumentReference/351ea353-4dc6-b0a8-2a70-0e5478e8171e') -('36d0d49a-6346-2856-d614-3f0a1ae85685', 'current', '34111-5', 'http://loinc.org', 'Emergency department note', None, None, None, datetime.date(2018, 7, 21), datetime.date(2018, 7, 16), datetime.date(2018, 7, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/f9399f0d-5401-09f3-d4ff-89b1aa51b9c8', 'Encounter/6a952afd-3be5-e27e-9e05-5a1e085e34d0', 'DocumentReference/36d0d49a-6346-2856-d614-3f0a1ae85685') -('36d0d49a-6346-2856-d614-3f0a1ae85685', 'current', '51847-2', 'http://loinc.org', 'Evaluation + Plan note', None, None, None, datetime.date(2018, 7, 21), datetime.date(2018, 7, 16), datetime.date(2018, 7, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/f9399f0d-5401-09f3-d4ff-89b1aa51b9c8', 'Encounter/6a952afd-3be5-e27e-9e05-5a1e085e34d0', 'DocumentReference/36d0d49a-6346-2856-d614-3f0a1ae85685') -('37c2d2ba-1976-1167-9bf6-7eb17f3fa35f', 'current', '34111-5', 'http://loinc.org', 'Emergency department note', None, None, None, datetime.date(2018, 6, 13), datetime.date(2018, 6, 11), datetime.date(2018, 6, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/8022fbbe-aaa4-056c-d0f5-ec074bf0656c', 'Encounter/e922a884-7039-a171-a65e-78051fe7afe6', 'DocumentReference/37c2d2ba-1976-1167-9bf6-7eb17f3fa35f') -('37c2d2ba-1976-1167-9bf6-7eb17f3fa35f', 'current', '51847-2', 'http://loinc.org', 'Evaluation + Plan note', None, None, None, datetime.date(2018, 6, 13), datetime.date(2018, 6, 11), datetime.date(2018, 6, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/8022fbbe-aaa4-056c-d0f5-ec074bf0656c', 'Encounter/e922a884-7039-a171-a65e-78051fe7afe6', 'DocumentReference/37c2d2ba-1976-1167-9bf6-7eb17f3fa35f') -('3ebf29a1-a116-9d17-5e9a-bad0d6c2d756', 'current', '34111-5', 'http://loinc.org', 'Emergency department note', None, None, None, datetime.date(2018, 7, 28), datetime.date(2018, 7, 23), datetime.date(2018, 7, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/0b052286-9534-99a8-8d5e-06c2c04a7df7', 'Encounter/e5dabcb6-1d7a-7467-dbba-b864d0d5f5b0', 'DocumentReference/3ebf29a1-a116-9d17-5e9a-bad0d6c2d756') -('3ebf29a1-a116-9d17-5e9a-bad0d6c2d756', 'current', '51847-2', 'http://loinc.org', 'Evaluation + Plan note', None, None, None, datetime.date(2018, 7, 28), datetime.date(2018, 7, 23), datetime.date(2018, 7, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/0b052286-9534-99a8-8d5e-06c2c04a7df7', 'Encounter/e5dabcb6-1d7a-7467-dbba-b864d0d5f5b0', 'DocumentReference/3ebf29a1-a116-9d17-5e9a-bad0d6c2d756') -('3f0e9271-a486-797d-978a-fb2d32d37d47', 'current', '34111-5', 'http://loinc.org', 'Emergency department note', None, None, None, datetime.date(2018, 6, 21), datetime.date(2018, 6, 18), datetime.date(2018, 6, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/a46846ca-3f95-2cbb-3a9d-5eae150a0273', 'Encounter/5c3450fb-12f0-08f3-6e4d-8a5e433e19a4', 'DocumentReference/3f0e9271-a486-797d-978a-fb2d32d37d47') -('3f0e9271-a486-797d-978a-fb2d32d37d47', 'current', '51847-2', 'http://loinc.org', 'Evaluation + Plan note', None, None, None, datetime.date(2018, 6, 21), datetime.date(2018, 6, 18), datetime.date(2018, 6, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/a46846ca-3f95-2cbb-3a9d-5eae150a0273', 'Encounter/5c3450fb-12f0-08f3-6e4d-8a5e433e19a4', 'DocumentReference/3f0e9271-a486-797d-978a-fb2d32d37d47') -('3f578a1b-f50a-9333-3030-306982950658', 'current', '34111-5', 'http://loinc.org', 'Emergency department note', None, None, None, datetime.date(2018, 6, 13), datetime.date(2018, 6, 11), datetime.date(2018, 6, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/3cf7af45-2bee-aa9c-d524-40b487149d60', 'Encounter/d2782687-6885-037c-957d-579fbd681d2a', 'DocumentReference/3f578a1b-f50a-9333-3030-306982950658') -('3f578a1b-f50a-9333-3030-306982950658', 'current', '51847-2', 'http://loinc.org', 'Evaluation + Plan note', None, None, None, datetime.date(2018, 6, 13), datetime.date(2018, 6, 11), datetime.date(2018, 6, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/3cf7af45-2bee-aa9c-d524-40b487149d60', 'Encounter/d2782687-6885-037c-957d-579fbd681d2a', 'DocumentReference/3f578a1b-f50a-9333-3030-306982950658') -('406679b2-a02c-0003-3b17-56ba373fccff', 'current', '34111-5', 'http://loinc.org', 'Emergency department note', None, None, None, datetime.date(2018, 7, 21), datetime.date(2018, 7, 16), datetime.date(2018, 7, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/0734762a-9db6-22fc-b595-c3e472bb2a9a', 'Encounter/2f55edb9-a906-0b40-e183-89b1d65d1aa1', 'DocumentReference/406679b2-a02c-0003-3b17-56ba373fccff') -('406679b2-a02c-0003-3b17-56ba373fccff', 'current', '51847-2', 'http://loinc.org', 'Evaluation + Plan note', None, None, None, datetime.date(2018, 7, 21), datetime.date(2018, 7, 16), datetime.date(2018, 7, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/0734762a-9db6-22fc-b595-c3e472bb2a9a', 'Encounter/2f55edb9-a906-0b40-e183-89b1d65d1aa1', 'DocumentReference/406679b2-a02c-0003-3b17-56ba373fccff') -('41eb62dd-7032-e98d-84c6-d494ad8c877b', 'current', '34111-5', 'http://loinc.org', 'Emergency department note', None, 'final', None, datetime.date(2018, 7, 31), datetime.date(2018, 7, 30), datetime.date(2018, 7, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/2a0e1946-acf6-5a7e-9399-a9cbc4730199', 'Encounter/aabb3ac3-c4a3-f613-9507-63280adb9209', 'DocumentReference/41eb62dd-7032-e98d-84c6-d494ad8c877b') -('41eb62dd-7032-e98d-84c6-d494ad8c877b', 'current', '51847-2', 'http://loinc.org', 'Evaluation + Plan note', None, 'final', None, datetime.date(2018, 7, 31), datetime.date(2018, 7, 30), datetime.date(2018, 7, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/2a0e1946-acf6-5a7e-9399-a9cbc4730199', 'Encounter/aabb3ac3-c4a3-f613-9507-63280adb9209', 'DocumentReference/41eb62dd-7032-e98d-84c6-d494ad8c877b') -('4390dbd1-3bdf-e516-9fe0-a8180181507f', 'current', '34111-5', 'http://loinc.org', 'Emergency department note', None, 'amended', None, datetime.date(2018, 6, 3), datetime.date(2018, 5, 28), datetime.date(2018, 6, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/e80dda2c-a260-dbf7-3167-bf0945f3a91d', 'Encounter/029d1814-d7bf-0624-524d-7ccda5f320f6', 'DocumentReference/4390dbd1-3bdf-e516-9fe0-a8180181507f') -('4390dbd1-3bdf-e516-9fe0-a8180181507f', 'current', '51847-2', 'http://loinc.org', 'Evaluation + Plan note', None, 'amended', None, datetime.date(2018, 6, 3), datetime.date(2018, 5, 28), datetime.date(2018, 6, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/e80dda2c-a260-dbf7-3167-bf0945f3a91d', 'Encounter/029d1814-d7bf-0624-524d-7ccda5f320f6', 'DocumentReference/4390dbd1-3bdf-e516-9fe0-a8180181507f') -('4390dbd1-3bdf-e516-9fe0-a8180181507f-error', 'current', '34111-5', 'http://loinc.org', 'Emergency department note', None, 'entered-in-error', None, datetime.date(2018, 6, 3), datetime.date(2018, 5, 28), datetime.date(2018, 6, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/e80dda2c-a260-dbf7-3167-bf0945f3a91d', 'Encounter/029d1814-d7bf-0624-524d-7ccda5f320f6', 'DocumentReference/4390dbd1-3bdf-e516-9fe0-a8180181507f-error') -('4390dbd1-3bdf-e516-9fe0-a8180181507f-error', 'current', '51847-2', 'http://loinc.org', 'Evaluation + Plan note', None, 'entered-in-error', None, datetime.date(2018, 6, 3), datetime.date(2018, 5, 28), datetime.date(2018, 6, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/e80dda2c-a260-dbf7-3167-bf0945f3a91d', 'Encounter/029d1814-d7bf-0624-524d-7ccda5f320f6', 'DocumentReference/4390dbd1-3bdf-e516-9fe0-a8180181507f-error') -('4439aa6e-fbc2-21a1-208e-095907104a65', 'current', '34111-5', 'http://loinc.org', 'Emergency department note', None, None, None, datetime.date(2018, 6, 30), datetime.date(2018, 6, 25), datetime.date(2018, 6, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/82b8a670-4700-30e8-24a0-b83efa3c5e0a', 'Encounter/75b68644-535d-bdc1-4c31-aa9fe7e1822f', 'DocumentReference/4439aa6e-fbc2-21a1-208e-095907104a65') -('4439aa6e-fbc2-21a1-208e-095907104a65', 'current', '51847-2', 'http://loinc.org', 'Evaluation + Plan note', None, None, None, datetime.date(2018, 6, 30), datetime.date(2018, 6, 25), datetime.date(2018, 6, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/82b8a670-4700-30e8-24a0-b83efa3c5e0a', 'Encounter/75b68644-535d-bdc1-4c31-aa9fe7e1822f', 'DocumentReference/4439aa6e-fbc2-21a1-208e-095907104a65') -('45160ef5-42e8-7239-6633-904308273198', 'current', '34111-5', 'http://loinc.org', 'Emergency department note', None, None, None, datetime.date(2018, 7, 13), datetime.date(2018, 7, 9), datetime.date(2018, 7, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/3627adb8-f741-acf3-2dd6-10f3bcbe1077', 'Encounter/bca7cabc-b2fc-8a08-c69b-5bc0afa20d80', 'DocumentReference/45160ef5-42e8-7239-6633-904308273198') -('45160ef5-42e8-7239-6633-904308273198', 'current', '51847-2', 'http://loinc.org', 'Evaluation + Plan note', None, None, None, datetime.date(2018, 7, 13), datetime.date(2018, 7, 9), datetime.date(2018, 7, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/3627adb8-f741-acf3-2dd6-10f3bcbe1077', 'Encounter/bca7cabc-b2fc-8a08-c69b-5bc0afa20d80', 'DocumentReference/45160ef5-42e8-7239-6633-904308273198') -('4711ca43-989d-a8f9-5f32-0102640804cf', 'current', '34111-5', 'http://loinc.org', 'Emergency department note', None, None, None, datetime.date(2018, 7, 19), datetime.date(2018, 7, 16), datetime.date(2018, 7, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/d3c0274f-f42b-8d2b-15f2-82331e723383', 'Encounter/6565ef5c-30b9-8697-6ca6-2b77894d5437', 'DocumentReference/4711ca43-989d-a8f9-5f32-0102640804cf') -('4711ca43-989d-a8f9-5f32-0102640804cf', 'current', '51847-2', 'http://loinc.org', 'Evaluation + Plan note', None, None, None, datetime.date(2018, 7, 19), datetime.date(2018, 7, 16), datetime.date(2018, 7, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/d3c0274f-f42b-8d2b-15f2-82331e723383', 'Encounter/6565ef5c-30b9-8697-6ca6-2b77894d5437', 'DocumentReference/4711ca43-989d-a8f9-5f32-0102640804cf') -('48693636-4eec-ad3d-b71d-8f650bd0a6f1', 'current', '34111-5', 'http://loinc.org', 'Emergency department note', None, None, None, datetime.date(2018, 6, 7), datetime.date(2018, 6, 4), datetime.date(2018, 6, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/c7ad408d-fcae-b54a-eb1d-26d48f7a5f84', 'Encounter/02eb4e14-1a6f-d968-2c26-c0cf5023afe0', 'DocumentReference/48693636-4eec-ad3d-b71d-8f650bd0a6f1') -('48693636-4eec-ad3d-b71d-8f650bd0a6f1', 'current', '51847-2', 'http://loinc.org', 'Evaluation + Plan note', None, None, None, datetime.date(2018, 6, 7), datetime.date(2018, 6, 4), datetime.date(2018, 6, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/c7ad408d-fcae-b54a-eb1d-26d48f7a5f84', 'Encounter/02eb4e14-1a6f-d968-2c26-c0cf5023afe0', 'DocumentReference/48693636-4eec-ad3d-b71d-8f650bd0a6f1') -('48933dd8-3fcf-416e-89ca-27851e45391f', 'current', '34111-5', 'http://loinc.org', 'Emergency department note', None, None, None, datetime.date(2018, 7, 29), datetime.date(2018, 7, 23), datetime.date(2018, 7, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/7cef0e6f-9aea-4079-dfc6-18a96454708e', 'Encounter/d735c414-9dd3-c9b1-285c-8da79a7fbbdf', 'DocumentReference/48933dd8-3fcf-416e-89ca-27851e45391f') -('48933dd8-3fcf-416e-89ca-27851e45391f', 'current', '51847-2', 'http://loinc.org', 'Evaluation + Plan note', None, None, None, datetime.date(2018, 7, 29), datetime.date(2018, 7, 23), datetime.date(2018, 7, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/7cef0e6f-9aea-4079-dfc6-18a96454708e', 'Encounter/d735c414-9dd3-c9b1-285c-8da79a7fbbdf', 'DocumentReference/48933dd8-3fcf-416e-89ca-27851e45391f') -('4b2e99d5-d4c2-fd1f-a5fd-96fe9546b58a', 'current', '34111-5', 'http://loinc.org', 'Emergency department note', None, None, None, datetime.date(2018, 7, 10), datetime.date(2018, 7, 9), datetime.date(2018, 7, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/6385ddd7-2639-6505-3789-0521b8f66c8b', 'Encounter/fd0754a4-e96d-cba7-b3c0-77697a09c86e', 'DocumentReference/4b2e99d5-d4c2-fd1f-a5fd-96fe9546b58a') -('4b2e99d5-d4c2-fd1f-a5fd-96fe9546b58a', 'current', '51847-2', 'http://loinc.org', 'Evaluation + Plan note', None, None, None, datetime.date(2018, 7, 10), datetime.date(2018, 7, 9), datetime.date(2018, 7, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/6385ddd7-2639-6505-3789-0521b8f66c8b', 'Encounter/fd0754a4-e96d-cba7-b3c0-77697a09c86e', 'DocumentReference/4b2e99d5-d4c2-fd1f-a5fd-96fe9546b58a') -('99b390f4-1bcb-21ec-85d5-85cbb74e86ae', 'current', '34111-5', 'http://loinc.org', 'Emergency department note', None, None, None, datetime.date(2018, 7, 13), datetime.date(2018, 7, 9), datetime.date(2018, 7, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/9eaa056b-1efc-0cc8-70ff-62c8f704cc13', 'Encounter/5c994000-aa78-2be5-e6cf-99f230d50c2f', 'DocumentReference/99b390f4-1bcb-21ec-85d5-85cbb74e86ae') -('99b390f4-1bcb-21ec-85d5-85cbb74e86ae', 'current', '51847-2', 'http://loinc.org', 'Evaluation + Plan note', None, None, None, datetime.date(2018, 7, 13), datetime.date(2018, 7, 9), datetime.date(2018, 7, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/9eaa056b-1efc-0cc8-70ff-62c8f704cc13', 'Encounter/5c994000-aa78-2be5-e6cf-99f230d50c2f', 'DocumentReference/99b390f4-1bcb-21ec-85d5-85cbb74e86ae') -('99d49a34-c515-23a1-c3e4-ef73c3cef727', 'current', '34111-5', 'http://loinc.org', 'Emergency department note', None, None, None, datetime.date(2018, 7, 26), datetime.date(2018, 7, 23), datetime.date(2018, 7, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/cc9fb8e2-fe52-b72a-aebb-9d10260f121b', 'Encounter/683b04eb-663a-849f-715f-4ccd70bf1524', 'DocumentReference/99d49a34-c515-23a1-c3e4-ef73c3cef727') -('99d49a34-c515-23a1-c3e4-ef73c3cef727', 'current', '51847-2', 'http://loinc.org', 'Evaluation + Plan note', None, None, None, datetime.date(2018, 7, 26), datetime.date(2018, 7, 23), datetime.date(2018, 7, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/cc9fb8e2-fe52-b72a-aebb-9d10260f121b', 'Encounter/683b04eb-663a-849f-715f-4ccd70bf1524', 'DocumentReference/99d49a34-c515-23a1-c3e4-ef73c3cef727') -('99e26f8b-a5a2-ad5e-713a-16266b5991a1', 'current', '34111-5', 'http://loinc.org', 'Emergency department note', None, None, None, datetime.date(2018, 6, 29), datetime.date(2018, 6, 25), datetime.date(2018, 6, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/1c498b42-61fd-6341-69c3-053f6e4fe404', 'Encounter/e613f29d-7505-6f2e-a1f5-bfbec300752d', 'DocumentReference/99e26f8b-a5a2-ad5e-713a-16266b5991a1') -('99e26f8b-a5a2-ad5e-713a-16266b5991a1', 'current', '51847-2', 'http://loinc.org', 'Evaluation + Plan note', None, None, None, datetime.date(2018, 6, 29), datetime.date(2018, 6, 25), datetime.date(2018, 6, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/1c498b42-61fd-6341-69c3-053f6e4fe404', 'Encounter/e613f29d-7505-6f2e-a1f5-bfbec300752d', 'DocumentReference/99e26f8b-a5a2-ad5e-713a-16266b5991a1') -('9a50a40a-8099-5ab5-0903-1ba65d8c0905', 'current', '34111-5', 'http://loinc.org', 'Emergency department note', None, None, None, datetime.date(2018, 6, 14), datetime.date(2018, 6, 11), datetime.date(2018, 6, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/24906e2c-e556-71dc-23d9-3e1d5fb08986', 'Encounter/1154d05c-8727-9373-4224-25b9fdba9ab3', 'DocumentReference/9a50a40a-8099-5ab5-0903-1ba65d8c0905') -('9a50a40a-8099-5ab5-0903-1ba65d8c0905', 'current', '51847-2', 'http://loinc.org', 'Evaluation + Plan note', None, None, None, datetime.date(2018, 6, 14), datetime.date(2018, 6, 11), datetime.date(2018, 6, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/24906e2c-e556-71dc-23d9-3e1d5fb08986', 'Encounter/1154d05c-8727-9373-4224-25b9fdba9ab3', 'DocumentReference/9a50a40a-8099-5ab5-0903-1ba65d8c0905') -('9ca118c6-e354-5588-3cdc-77ee3b3c8711', 'current', '34111-5', 'http://loinc.org', 'Emergency department note', None, None, None, datetime.date(2018, 7, 28), datetime.date(2018, 7, 23), datetime.date(2018, 7, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/2da1bee2-2bc2-4511-84e1-42860310e2fb', 'Encounter/d5f342b7-017c-f2e7-8697-5a038c91518e', 'DocumentReference/9ca118c6-e354-5588-3cdc-77ee3b3c8711') -('9ca118c6-e354-5588-3cdc-77ee3b3c8711', 'current', '51847-2', 'http://loinc.org', 'Evaluation + Plan note', None, None, None, datetime.date(2018, 7, 28), datetime.date(2018, 7, 23), datetime.date(2018, 7, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/2da1bee2-2bc2-4511-84e1-42860310e2fb', 'Encounter/d5f342b7-017c-f2e7-8697-5a038c91518e', 'DocumentReference/9ca118c6-e354-5588-3cdc-77ee3b3c8711') -('a1b69e45-11f8-a49f-170e-32004c70e842', 'current', '34111-5', 'http://loinc.org', 'Emergency department note', None, None, None, datetime.date(2018, 7, 11), datetime.date(2018, 7, 9), datetime.date(2018, 7, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/5ce2e599-fb6e-9b4d-3c2e-87310619b957', 'Encounter/4b03a408-6694-88e3-0e63-3ee464ecd6cd', 'DocumentReference/a1b69e45-11f8-a49f-170e-32004c70e842') -('a1b69e45-11f8-a49f-170e-32004c70e842', 'current', '51847-2', 'http://loinc.org', 'Evaluation + Plan note', None, None, None, datetime.date(2018, 7, 11), datetime.date(2018, 7, 9), datetime.date(2018, 7, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/5ce2e599-fb6e-9b4d-3c2e-87310619b957', 'Encounter/4b03a408-6694-88e3-0e63-3ee464ecd6cd', 'DocumentReference/a1b69e45-11f8-a49f-170e-32004c70e842') -('a3964c82-0605-c2b2-97dc-0de17a1ec0ef', 'current', '34111-5', 'http://loinc.org', 'Emergency department note', None, None, None, datetime.date(2018, 6, 17), datetime.date(2018, 6, 11), datetime.date(2018, 6, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/7f941bcc-e7b2-99e1-585f-129d0ef1c13d', 'Encounter/65f8fdca-a949-80a0-8072-094e9aaee474', 'DocumentReference/a3964c82-0605-c2b2-97dc-0de17a1ec0ef') -('a3964c82-0605-c2b2-97dc-0de17a1ec0ef', 'current', '51847-2', 'http://loinc.org', 'Evaluation + Plan note', None, None, None, datetime.date(2018, 6, 17), datetime.date(2018, 6, 11), datetime.date(2018, 6, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/7f941bcc-e7b2-99e1-585f-129d0ef1c13d', 'Encounter/65f8fdca-a949-80a0-8072-094e9aaee474', 'DocumentReference/a3964c82-0605-c2b2-97dc-0de17a1ec0ef') -('a5231f35-ad14-580e-1888-55c1b383aa11', 'current', '34111-5', 'http://loinc.org', 'Emergency department note', None, None, None, datetime.date(2018, 7, 2), datetime.date(2018, 7, 2), datetime.date(2018, 7, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/3ae095ec-8fe0-133b-36d4-8785a6ad8df3', 'Encounter/75312bd2-d5ac-c62e-c9df-0004783725c7', 'DocumentReference/a5231f35-ad14-580e-1888-55c1b383aa11') -('a5231f35-ad14-580e-1888-55c1b383aa11', 'current', '51847-2', 'http://loinc.org', 'Evaluation + Plan note', None, None, None, datetime.date(2018, 7, 2), datetime.date(2018, 7, 2), datetime.date(2018, 7, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/3ae095ec-8fe0-133b-36d4-8785a6ad8df3', 'Encounter/75312bd2-d5ac-c62e-c9df-0004783725c7', 'DocumentReference/a5231f35-ad14-580e-1888-55c1b383aa11') -('a59ca653-b95d-09d2-9fa5-a1b492d85a5f', 'current', '34111-5', 'http://loinc.org', 'Emergency department note', None, None, None, datetime.date(2018, 6, 28), datetime.date(2018, 6, 25), datetime.date(2018, 6, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/c20e5afd-30df-ac3d-6684-cc29438a9bc4', 'Encounter/b864bcd8-14e0-8bec-b7cc-f8629d91470e', 'DocumentReference/a59ca653-b95d-09d2-9fa5-a1b492d85a5f') -('a59ca653-b95d-09d2-9fa5-a1b492d85a5f', 'current', '51847-2', 'http://loinc.org', 'Evaluation + Plan note', None, None, None, datetime.date(2018, 6, 28), datetime.date(2018, 6, 25), datetime.date(2018, 6, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/c20e5afd-30df-ac3d-6684-cc29438a9bc4', 'Encounter/b864bcd8-14e0-8bec-b7cc-f8629d91470e', 'DocumentReference/a59ca653-b95d-09d2-9fa5-a1b492d85a5f') -('a69150c5-2fbe-2284-1eb5-e11146858a22', 'current', '34111-5', 'http://loinc.org', 'Emergency department note', None, None, None, datetime.date(2018, 6, 1), datetime.date(2018, 5, 28), datetime.date(2018, 6, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/9c8d8539-0b1e-73e2-b64f-83f1ea601fa4', 'Encounter/f2752dd7-1bf1-739d-dd8c-40122d0b63bc', 'DocumentReference/a69150c5-2fbe-2284-1eb5-e11146858a22') -('a69150c5-2fbe-2284-1eb5-e11146858a22', 'current', '51847-2', 'http://loinc.org', 'Evaluation + Plan note', None, None, None, datetime.date(2018, 6, 1), datetime.date(2018, 5, 28), datetime.date(2018, 6, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/9c8d8539-0b1e-73e2-b64f-83f1ea601fa4', 'Encounter/f2752dd7-1bf1-739d-dd8c-40122d0b63bc', 'DocumentReference/a69150c5-2fbe-2284-1eb5-e11146858a22') -('a7115116-f8da-3960-e3ed-f1f0d89646c3', 'current', '34111-5', 'http://loinc.org', 'Emergency department note', None, None, None, datetime.date(2018, 6, 2), datetime.date(2018, 5, 28), datetime.date(2018, 6, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/8877ef1f-7cd7-3242-d7f0-73cf3f7165f4', 'Encounter/299b6495-3fe7-8db3-c494-6e1ce8b7986d', 'DocumentReference/a7115116-f8da-3960-e3ed-f1f0d89646c3') -('a7115116-f8da-3960-e3ed-f1f0d89646c3', 'current', '51847-2', 'http://loinc.org', 'Evaluation + Plan note', None, None, None, datetime.date(2018, 6, 2), datetime.date(2018, 5, 28), datetime.date(2018, 6, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/8877ef1f-7cd7-3242-d7f0-73cf3f7165f4', 'Encounter/299b6495-3fe7-8db3-c494-6e1ce8b7986d', 'DocumentReference/a7115116-f8da-3960-e3ed-f1f0d89646c3') -('a79da4dd-83bc-5b6a-db34-bd35b3acbd2c', 'current', '34111-5', 'http://loinc.org', 'Emergency department note', None, None, None, datetime.date(2018, 6, 6), datetime.date(2018, 6, 4), datetime.date(2018, 6, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/19158de4-66a2-f70f-e3bf-4396b312c8f1', 'Encounter/ed151e04-3dd6-8cb7-a3e5-777c8a8667f1', 'DocumentReference/a79da4dd-83bc-5b6a-db34-bd35b3acbd2c') -('a79da4dd-83bc-5b6a-db34-bd35b3acbd2c', 'current', '51847-2', 'http://loinc.org', 'Evaluation + Plan note', None, None, None, datetime.date(2018, 6, 6), datetime.date(2018, 6, 4), datetime.date(2018, 6, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/19158de4-66a2-f70f-e3bf-4396b312c8f1', 'Encounter/ed151e04-3dd6-8cb7-a3e5-777c8a8667f1', 'DocumentReference/a79da4dd-83bc-5b6a-db34-bd35b3acbd2c') -('a95df5ea-7005-9e98-e97a-1ade6967b585', 'current', '34111-5', 'http://loinc.org', 'Emergency department note', None, None, None, datetime.date(2018, 6, 16), datetime.date(2018, 6, 11), datetime.date(2018, 6, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/16be855b-ece2-8b96-1ef9-a4d93adf3289', 'Encounter/83d0d564-3bbf-48eb-7445-bd2b81130671', 'DocumentReference/a95df5ea-7005-9e98-e97a-1ade6967b585') -('a95df5ea-7005-9e98-e97a-1ade6967b585', 'current', '51847-2', 'http://loinc.org', 'Evaluation + Plan note', None, None, None, datetime.date(2018, 6, 16), datetime.date(2018, 6, 11), datetime.date(2018, 6, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/16be855b-ece2-8b96-1ef9-a4d93adf3289', 'Encounter/83d0d564-3bbf-48eb-7445-bd2b81130671', 'DocumentReference/a95df5ea-7005-9e98-e97a-1ade6967b585') -('a96ba3b7-a461-5849-1881-d372e0460ccc', 'current', '34111-5', 'http://loinc.org', 'Emergency department note', None, None, None, datetime.date(2018, 7, 14), datetime.date(2018, 7, 9), datetime.date(2018, 7, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/26a3984f-b2a8-e67f-7abc-ff147a0e6e35', 'Encounter/79d8f213-7847-646b-8a66-5da208cc1c27', 'DocumentReference/a96ba3b7-a461-5849-1881-d372e0460ccc') -('a96ba3b7-a461-5849-1881-d372e0460ccc', 'current', '51847-2', 'http://loinc.org', 'Evaluation + Plan note', None, None, None, datetime.date(2018, 7, 14), datetime.date(2018, 7, 9), datetime.date(2018, 7, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/26a3984f-b2a8-e67f-7abc-ff147a0e6e35', 'Encounter/79d8f213-7847-646b-8a66-5da208cc1c27', 'DocumentReference/a96ba3b7-a461-5849-1881-d372e0460ccc') -('ac0439bc-e450-d339-da6d-5ead96d8b346', 'current', '34111-5', 'http://loinc.org', 'Emergency department note', None, None, None, datetime.date(2018, 7, 30), datetime.date(2018, 7, 30), datetime.date(2018, 7, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/2858705f-5af1-9869-4d94-894e09a9f99a', 'Encounter/de9d67de-6ae3-32f7-20f2-e719ae23a9a3', 'DocumentReference/ac0439bc-e450-d339-da6d-5ead96d8b346') -('ac0439bc-e450-d339-da6d-5ead96d8b346', 'current', '51847-2', 'http://loinc.org', 'Evaluation + Plan note', None, None, None, datetime.date(2018, 7, 30), datetime.date(2018, 7, 30), datetime.date(2018, 7, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/2858705f-5af1-9869-4d94-894e09a9f99a', 'Encounter/de9d67de-6ae3-32f7-20f2-e719ae23a9a3', 'DocumentReference/ac0439bc-e450-d339-da6d-5ead96d8b346') -('ad2bee76-6e59-5d8b-21ed-b30cdb784198', 'current', '34111-5', 'http://loinc.org', 'Emergency department note', None, None, None, datetime.date(2018, 7, 9), datetime.date(2018, 7, 9), datetime.date(2018, 7, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/e455ca3f-fc16-6ffc-297a-adc27e2db183', 'Encounter/98d4bd14-d78e-debb-e7dc-2df7786aedf3', 'DocumentReference/ad2bee76-6e59-5d8b-21ed-b30cdb784198') -('ad2bee76-6e59-5d8b-21ed-b30cdb784198', 'current', '51847-2', 'http://loinc.org', 'Evaluation + Plan note', None, None, None, datetime.date(2018, 7, 9), datetime.date(2018, 7, 9), datetime.date(2018, 7, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/e455ca3f-fc16-6ffc-297a-adc27e2db183', 'Encounter/98d4bd14-d78e-debb-e7dc-2df7786aedf3', 'DocumentReference/ad2bee76-6e59-5d8b-21ed-b30cdb784198') -('b1f5c114-8e28-08c0-0193-0855aa10c97f', 'current', '34111-5', 'http://loinc.org', 'Emergency department note', None, None, None, datetime.date(2018, 7, 2), datetime.date(2018, 7, 2), datetime.date(2018, 7, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/c7c5c028-f1fb-962b-8db2-dfd4c6d6b02a', 'Encounter/aa890974-162f-5906-dc71-2bb6d2185314', 'DocumentReference/b1f5c114-8e28-08c0-0193-0855aa10c97f') -('b1f5c114-8e28-08c0-0193-0855aa10c97f', 'current', '51847-2', 'http://loinc.org', 'Evaluation + Plan note', None, None, None, datetime.date(2018, 7, 2), datetime.date(2018, 7, 2), datetime.date(2018, 7, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/c7c5c028-f1fb-962b-8db2-dfd4c6d6b02a', 'Encounter/aa890974-162f-5906-dc71-2bb6d2185314', 'DocumentReference/b1f5c114-8e28-08c0-0193-0855aa10c97f') -('b2896621-57ef-1ad3-91c5-389dce96973b', 'current', '34111-5', 'http://loinc.org', 'Emergency department note', None, None, None, datetime.date(2018, 7, 7), datetime.date(2018, 7, 2), datetime.date(2018, 7, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/ac91b90d-97e4-4fc5-41cd-036bac49e6e8', 'Encounter/dc5ed645-3979-e765-3e03-6ba2173027c3', 'DocumentReference/b2896621-57ef-1ad3-91c5-389dce96973b') -('b2896621-57ef-1ad3-91c5-389dce96973b', 'current', '51847-2', 'http://loinc.org', 'Evaluation + Plan note', None, None, None, datetime.date(2018, 7, 7), datetime.date(2018, 7, 2), datetime.date(2018, 7, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/ac91b90d-97e4-4fc5-41cd-036bac49e6e8', 'Encounter/dc5ed645-3979-e765-3e03-6ba2173027c3', 'DocumentReference/b2896621-57ef-1ad3-91c5-389dce96973b') -('b3357397-9f4c-7d00-06af-18f03c63d583', 'current', '34111-5', 'http://loinc.org', 'Emergency department note', None, None, None, datetime.date(2018, 7, 15), datetime.date(2018, 7, 9), datetime.date(2018, 7, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/c1bfec36-dc2c-afc8-c767-3d35ed2bf6f0', 'Encounter/8ff1dc01-5a28-b2d8-3b42-4b7a7d539970', 'DocumentReference/b3357397-9f4c-7d00-06af-18f03c63d583') -('b3357397-9f4c-7d00-06af-18f03c63d583', 'current', '51847-2', 'http://loinc.org', 'Evaluation + Plan note', None, None, None, datetime.date(2018, 7, 15), datetime.date(2018, 7, 9), datetime.date(2018, 7, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/c1bfec36-dc2c-afc8-c767-3d35ed2bf6f0', 'Encounter/8ff1dc01-5a28-b2d8-3b42-4b7a7d539970', 'DocumentReference/b3357397-9f4c-7d00-06af-18f03c63d583') -('b339c2e8-35eb-1838-7eea-5a04c81695df', 'current', '34111-5', 'http://loinc.org', 'Emergency department note', None, None, None, datetime.date(2018, 6, 14), datetime.date(2018, 6, 11), datetime.date(2018, 6, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/267fc42d-cd9e-8527-1f9e-887fe7776147', 'Encounter/4c4d0730-201f-5b75-c657-8d0de09cc28f', 'DocumentReference/b339c2e8-35eb-1838-7eea-5a04c81695df') -('b339c2e8-35eb-1838-7eea-5a04c81695df', 'current', '51847-2', 'http://loinc.org', 'Evaluation + Plan note', None, None, None, datetime.date(2018, 6, 14), datetime.date(2018, 6, 11), datetime.date(2018, 6, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/267fc42d-cd9e-8527-1f9e-887fe7776147', 'Encounter/4c4d0730-201f-5b75-c657-8d0de09cc28f', 'DocumentReference/b339c2e8-35eb-1838-7eea-5a04c81695df') -('b39532e8-ee15-a7c4-cac5-353a8be67d15', 'current', '34111-5', 'http://loinc.org', 'Emergency department note', None, None, None, datetime.date(2018, 6, 8), datetime.date(2018, 6, 4), datetime.date(2018, 6, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/6a883108-7b87-120b-d163-d369336e04e5', 'Encounter/2b1ee164-6c87-420d-a9e2-6c235ebeef71', 'DocumentReference/b39532e8-ee15-a7c4-cac5-353a8be67d15') -('b39532e8-ee15-a7c4-cac5-353a8be67d15', 'current', '51847-2', 'http://loinc.org', 'Evaluation + Plan note', None, None, None, datetime.date(2018, 6, 8), datetime.date(2018, 6, 4), datetime.date(2018, 6, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/6a883108-7b87-120b-d163-d369336e04e5', 'Encounter/2b1ee164-6c87-420d-a9e2-6c235ebeef71', 'DocumentReference/b39532e8-ee15-a7c4-cac5-353a8be67d15') -('b44d277c-7c09-a39b-97e9-1e96d71b6978', 'current', '34111-5', 'http://loinc.org', 'Emergency department note', None, None, None, datetime.date(2018, 6, 15), datetime.date(2018, 6, 11), datetime.date(2018, 6, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/7bf52d54-0d2a-265a-15aa-eeed7aaf4af6', 'Encounter/ba84689e-2f9f-7cea-af1f-d69ffdd3a3eb', 'DocumentReference/b44d277c-7c09-a39b-97e9-1e96d71b6978') -('b44d277c-7c09-a39b-97e9-1e96d71b6978', 'current', '51847-2', 'http://loinc.org', 'Evaluation + Plan note', None, None, None, datetime.date(2018, 6, 15), datetime.date(2018, 6, 11), datetime.date(2018, 6, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/7bf52d54-0d2a-265a-15aa-eeed7aaf4af6', 'Encounter/ba84689e-2f9f-7cea-af1f-d69ffdd3a3eb', 'DocumentReference/b44d277c-7c09-a39b-97e9-1e96d71b6978') -('b58f7768-64be-6c0f-1b82-3deffdef1076', 'current', '34111-5', 'http://loinc.org', 'Emergency department note', None, None, None, datetime.date(2018, 6, 29), datetime.date(2018, 6, 25), datetime.date(2018, 6, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/a28be3e1-a6bd-7df4-fc81-1140848f8453', 'Encounter/91f94a9d-69a7-e30a-cd1a-68c52dc01e70', 'DocumentReference/b58f7768-64be-6c0f-1b82-3deffdef1076') -('b58f7768-64be-6c0f-1b82-3deffdef1076', 'current', '51847-2', 'http://loinc.org', 'Evaluation + Plan note', None, None, None, datetime.date(2018, 6, 29), datetime.date(2018, 6, 25), datetime.date(2018, 6, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/a28be3e1-a6bd-7df4-fc81-1140848f8453', 'Encounter/91f94a9d-69a7-e30a-cd1a-68c52dc01e70', 'DocumentReference/b58f7768-64be-6c0f-1b82-3deffdef1076') -('b73493d0-e2f4-9aa6-cdad-920f7c126d6c', 'current', '34111-5', 'http://loinc.org', 'Emergency department note', None, None, None, datetime.date(2018, 7, 16), datetime.date(2018, 7, 16), datetime.date(2018, 7, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/50f8b42e-17a6-e932-8546-da94004c597c', 'Encounter/37604257-be1a-120f-81ee-336f81603f92', 'DocumentReference/b73493d0-e2f4-9aa6-cdad-920f7c126d6c') -('b73493d0-e2f4-9aa6-cdad-920f7c126d6c', 'current', '51847-2', 'http://loinc.org', 'Evaluation + Plan note', None, None, None, datetime.date(2018, 7, 16), datetime.date(2018, 7, 16), datetime.date(2018, 7, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/50f8b42e-17a6-e932-8546-da94004c597c', 'Encounter/37604257-be1a-120f-81ee-336f81603f92', 'DocumentReference/b73493d0-e2f4-9aa6-cdad-920f7c126d6c') -('b7b68006-53d5-b823-d193-56b262f45e8b', 'current', '34111-5', 'http://loinc.org', 'Emergency department note', None, None, None, datetime.date(2018, 7, 19), datetime.date(2018, 7, 16), datetime.date(2018, 7, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/ad3ed58a-5645-af0a-eeca-ab543123a8aa', 'Encounter/03e34b19-2889-b828-792d-2a83400c55be', 'DocumentReference/b7b68006-53d5-b823-d193-56b262f45e8b') -('b7b68006-53d5-b823-d193-56b262f45e8b', 'current', '51847-2', 'http://loinc.org', 'Evaluation + Plan note', None, None, None, datetime.date(2018, 7, 19), datetime.date(2018, 7, 16), datetime.date(2018, 7, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/ad3ed58a-5645-af0a-eeca-ab543123a8aa', 'Encounter/03e34b19-2889-b828-792d-2a83400c55be', 'DocumentReference/b7b68006-53d5-b823-d193-56b262f45e8b') -('b953a85f-f18b-d7a3-8974-ba44e0a3141c', 'current', '34111-5', 'http://loinc.org', 'Emergency department note', None, None, None, datetime.date(2018, 6, 5), datetime.date(2018, 6, 4), datetime.date(2018, 6, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/a5bc08ea-9462-c4f5-1bd2-ff342598ac99', 'Encounter/f964be66-3fcd-95c8-0021-71c7d24c91b7', 'DocumentReference/b953a85f-f18b-d7a3-8974-ba44e0a3141c') -('b953a85f-f18b-d7a3-8974-ba44e0a3141c', 'current', '51847-2', 'http://loinc.org', 'Evaluation + Plan note', None, None, None, datetime.date(2018, 6, 5), datetime.date(2018, 6, 4), datetime.date(2018, 6, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/a5bc08ea-9462-c4f5-1bd2-ff342598ac99', 'Encounter/f964be66-3fcd-95c8-0021-71c7d24c91b7', 'DocumentReference/b953a85f-f18b-d7a3-8974-ba44e0a3141c') -('b985a70c-9504-b7b3-0707-f8381ba77976', 'current', '34111-5', 'http://loinc.org', 'Emergency department note', None, None, None, datetime.date(2018, 6, 7), datetime.date(2018, 6, 4), datetime.date(2018, 6, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/149de67a-2809-59a8-bfa2-36df509021dc', 'Encounter/beb26500-4ccd-ce0a-44f6-74f44be5fafe', 'DocumentReference/b985a70c-9504-b7b3-0707-f8381ba77976') -('b985a70c-9504-b7b3-0707-f8381ba77976', 'current', '51847-2', 'http://loinc.org', 'Evaluation + Plan note', None, None, None, datetime.date(2018, 6, 7), datetime.date(2018, 6, 4), datetime.date(2018, 6, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/149de67a-2809-59a8-bfa2-36df509021dc', 'Encounter/beb26500-4ccd-ce0a-44f6-74f44be5fafe', 'DocumentReference/b985a70c-9504-b7b3-0707-f8381ba77976') -('ba0abbd6-49a9-95fa-2396-7118c56da8c6', 'current', '34111-5', 'http://loinc.org', 'Emergency department note', None, None, None, datetime.date(2018, 6, 12), datetime.date(2018, 6, 11), datetime.date(2018, 6, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/9b17654f-a902-3d56-9000-4ade3dd3059f', 'Encounter/ca45bbef-ef2a-3b3c-ea5e-76bcd5865780', 'DocumentReference/ba0abbd6-49a9-95fa-2396-7118c56da8c6') -('ba0abbd6-49a9-95fa-2396-7118c56da8c6', 'current', '51847-2', 'http://loinc.org', 'Evaluation + Plan note', None, None, None, datetime.date(2018, 6, 12), datetime.date(2018, 6, 11), datetime.date(2018, 6, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/9b17654f-a902-3d56-9000-4ade3dd3059f', 'Encounter/ca45bbef-ef2a-3b3c-ea5e-76bcd5865780', 'DocumentReference/ba0abbd6-49a9-95fa-2396-7118c56da8c6') -('bcbaa9d3-d7cf-3f5f-44d3-32c8a267f991', 'current', '34111-5', 'http://loinc.org', 'Emergency department note', None, None, None, datetime.date(2018, 7, 2), datetime.date(2018, 7, 2), datetime.date(2018, 7, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/17fde357-dcc9-af8b-a8d3-4bd213afeb22', 'Encounter/32d0ae2d-1be8-9e90-a4da-4c222abd88a9', 'DocumentReference/bcbaa9d3-d7cf-3f5f-44d3-32c8a267f991') -('bcbaa9d3-d7cf-3f5f-44d3-32c8a267f991', 'current', '51847-2', 'http://loinc.org', 'Evaluation + Plan note', None, None, None, datetime.date(2018, 7, 2), datetime.date(2018, 7, 2), datetime.date(2018, 7, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/17fde357-dcc9-af8b-a8d3-4bd213afeb22', 'Encounter/32d0ae2d-1be8-9e90-a4da-4c222abd88a9', 'DocumentReference/bcbaa9d3-d7cf-3f5f-44d3-32c8a267f991') -('bd60a52b-65b9-f26d-03e4-282850509f03', 'current', '34111-5', 'http://loinc.org', 'Emergency department note', None, None, None, datetime.date(2018, 7, 10), datetime.date(2018, 7, 9), datetime.date(2018, 7, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/51032f44-d514-26e9-3e85-e956561c076e', 'Encounter/d73ed087-e0ae-78e0-7a05-1bac1060c476', 'DocumentReference/bd60a52b-65b9-f26d-03e4-282850509f03') -('bd60a52b-65b9-f26d-03e4-282850509f03', 'current', '51847-2', 'http://loinc.org', 'Evaluation + Plan note', None, None, None, datetime.date(2018, 7, 10), datetime.date(2018, 7, 9), datetime.date(2018, 7, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/51032f44-d514-26e9-3e85-e956561c076e', 'Encounter/d73ed087-e0ae-78e0-7a05-1bac1060c476', 'DocumentReference/bd60a52b-65b9-f26d-03e4-282850509f03') -('bfddb0ff-1296-107e-76ca-14b4a14db9ce', 'current', '34111-5', 'http://loinc.org', 'Emergency department note', None, None, None, datetime.date(2018, 7, 2), datetime.date(2018, 7, 2), datetime.date(2018, 7, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/26baae20-c8c5-003a-ab6b-ebcc49be20db', 'Encounter/c6ec2350-43d4-abab-2e84-4d2aadb337a7', 'DocumentReference/bfddb0ff-1296-107e-76ca-14b4a14db9ce') -('bfddb0ff-1296-107e-76ca-14b4a14db9ce', 'current', '51847-2', 'http://loinc.org', 'Evaluation + Plan note', None, None, None, datetime.date(2018, 7, 2), datetime.date(2018, 7, 2), datetime.date(2018, 7, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/26baae20-c8c5-003a-ab6b-ebcc49be20db', 'Encounter/c6ec2350-43d4-abab-2e84-4d2aadb337a7', 'DocumentReference/bfddb0ff-1296-107e-76ca-14b4a14db9ce') -('c18dbe84-be31-cee5-1f2e-cf163cdd3e3f', 'current', '34111-5', 'http://loinc.org', 'Emergency department note', None, None, None, datetime.date(2018, 7, 27), datetime.date(2018, 7, 23), datetime.date(2018, 7, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/a5b171a7-9b28-20e7-86a7-936ecbf55f36', 'Encounter/c4605953-3103-ede6-e0c0-e0588e6f019e', 'DocumentReference/c18dbe84-be31-cee5-1f2e-cf163cdd3e3f') -('c18dbe84-be31-cee5-1f2e-cf163cdd3e3f', 'current', '51847-2', 'http://loinc.org', 'Evaluation + Plan note', None, None, None, datetime.date(2018, 7, 27), datetime.date(2018, 7, 23), datetime.date(2018, 7, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/a5b171a7-9b28-20e7-86a7-936ecbf55f36', 'Encounter/c4605953-3103-ede6-e0c0-e0588e6f019e', 'DocumentReference/c18dbe84-be31-cee5-1f2e-cf163cdd3e3f') -('c6598486-8276-b44a-286e-b376143f7efc', 'current', '34111-5', 'http://loinc.org', 'Emergency department note', None, None, None, datetime.date(2018, 6, 25), datetime.date(2018, 6, 25), datetime.date(2018, 6, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/47c37c92-5932-9cfe-66be-208556780fe0', 'Encounter/b5974881-ae62-ddd6-b905-8c86c1ca9e33', 'DocumentReference/c6598486-8276-b44a-286e-b376143f7efc') -('c6598486-8276-b44a-286e-b376143f7efc', 'current', '51847-2', 'http://loinc.org', 'Evaluation + Plan note', None, None, None, datetime.date(2018, 6, 25), datetime.date(2018, 6, 25), datetime.date(2018, 6, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/47c37c92-5932-9cfe-66be-208556780fe0', 'Encounter/b5974881-ae62-ddd6-b905-8c86c1ca9e33', 'DocumentReference/c6598486-8276-b44a-286e-b376143f7efc') -('c6c64129-9dfa-840d-3309-a5590cc74f2e', 'current', '34111-5', 'http://loinc.org', 'Emergency department note', None, None, None, datetime.date(2018, 6, 15), datetime.date(2018, 6, 11), datetime.date(2018, 6, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/ad239efc-637c-e428-c829-b87e700d5446', 'Encounter/366df7d3-2ea9-db22-7cdd-60fa8a5c45ca', 'DocumentReference/c6c64129-9dfa-840d-3309-a5590cc74f2e') -('c6c64129-9dfa-840d-3309-a5590cc74f2e', 'current', '51847-2', 'http://loinc.org', 'Evaluation + Plan note', None, None, None, datetime.date(2018, 6, 15), datetime.date(2018, 6, 11), datetime.date(2018, 6, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/ad239efc-637c-e428-c829-b87e700d5446', 'Encounter/366df7d3-2ea9-db22-7cdd-60fa8a5c45ca', 'DocumentReference/c6c64129-9dfa-840d-3309-a5590cc74f2e') -('c84e67e9-4ea8-700b-9f2b-c0179e803d4f', 'current', '34111-5', 'http://loinc.org', 'Emergency department note', None, None, None, datetime.date(2018, 7, 15), datetime.date(2018, 7, 9), datetime.date(2018, 7, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/dffa62dc-8ec2-1cd6-ee75-f9156a5283fe', 'Encounter/11381dc6-0e06-da55-0735-d1e7bbf8bb35', 'DocumentReference/c84e67e9-4ea8-700b-9f2b-c0179e803d4f') -('c84e67e9-4ea8-700b-9f2b-c0179e803d4f', 'current', '51847-2', 'http://loinc.org', 'Evaluation + Plan note', None, None, None, datetime.date(2018, 7, 15), datetime.date(2018, 7, 9), datetime.date(2018, 7, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/dffa62dc-8ec2-1cd6-ee75-f9156a5283fe', 'Encounter/11381dc6-0e06-da55-0735-d1e7bbf8bb35', 'DocumentReference/c84e67e9-4ea8-700b-9f2b-c0179e803d4f') +('351ea353-4dc6-b0a8-2a70-0e5478e8171e', 'current', '34111-5', 'http://loinc.org', 'Emergency department note', None, None, datetime.date(2018, 6, 15), datetime.date(2018, 6, 15), datetime.date(2018, 6, 11), datetime.date(2018, 6, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/cb8c0665-30ee-479c-8994-d29f1a6848b0', 'Encounter/1d679c3a-2765-5e13-e2a3-4bd76a898fc6', 'DocumentReference/351ea353-4dc6-b0a8-2a70-0e5478e8171e') +('351ea353-4dc6-b0a8-2a70-0e5478e8171e', 'current', '51847-2', 'http://loinc.org', 'Evaluation + Plan note', None, None, datetime.date(2018, 6, 15), datetime.date(2018, 6, 15), datetime.date(2018, 6, 11), datetime.date(2018, 6, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/cb8c0665-30ee-479c-8994-d29f1a6848b0', 'Encounter/1d679c3a-2765-5e13-e2a3-4bd76a898fc6', 'DocumentReference/351ea353-4dc6-b0a8-2a70-0e5478e8171e') +('36d0d49a-6346-2856-d614-3f0a1ae85685', 'current', '34111-5', 'http://loinc.org', 'Emergency department note', None, None, datetime.date(2018, 7, 21), datetime.date(2018, 7, 21), datetime.date(2018, 7, 16), datetime.date(2018, 7, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/f9399f0d-5401-09f3-d4ff-89b1aa51b9c8', 'Encounter/6a952afd-3be5-e27e-9e05-5a1e085e34d0', 'DocumentReference/36d0d49a-6346-2856-d614-3f0a1ae85685') +('36d0d49a-6346-2856-d614-3f0a1ae85685', 'current', '51847-2', 'http://loinc.org', 'Evaluation + Plan note', None, None, datetime.date(2018, 7, 21), datetime.date(2018, 7, 21), datetime.date(2018, 7, 16), datetime.date(2018, 7, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/f9399f0d-5401-09f3-d4ff-89b1aa51b9c8', 'Encounter/6a952afd-3be5-e27e-9e05-5a1e085e34d0', 'DocumentReference/36d0d49a-6346-2856-d614-3f0a1ae85685') +('37c2d2ba-1976-1167-9bf6-7eb17f3fa35f', 'current', '34111-5', 'http://loinc.org', 'Emergency department note', None, None, datetime.date(2018, 6, 13), datetime.date(2018, 6, 13), datetime.date(2018, 6, 11), datetime.date(2018, 6, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/8022fbbe-aaa4-056c-d0f5-ec074bf0656c', 'Encounter/e922a884-7039-a171-a65e-78051fe7afe6', 'DocumentReference/37c2d2ba-1976-1167-9bf6-7eb17f3fa35f') +('37c2d2ba-1976-1167-9bf6-7eb17f3fa35f', 'current', '51847-2', 'http://loinc.org', 'Evaluation + Plan note', None, None, datetime.date(2018, 6, 13), datetime.date(2018, 6, 13), datetime.date(2018, 6, 11), datetime.date(2018, 6, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/8022fbbe-aaa4-056c-d0f5-ec074bf0656c', 'Encounter/e922a884-7039-a171-a65e-78051fe7afe6', 'DocumentReference/37c2d2ba-1976-1167-9bf6-7eb17f3fa35f') +('3ebf29a1-a116-9d17-5e9a-bad0d6c2d756', 'current', '34111-5', 'http://loinc.org', 'Emergency department note', None, None, datetime.date(2018, 7, 28), datetime.date(2018, 7, 28), datetime.date(2018, 7, 23), datetime.date(2018, 7, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/0b052286-9534-99a8-8d5e-06c2c04a7df7', 'Encounter/e5dabcb6-1d7a-7467-dbba-b864d0d5f5b0', 'DocumentReference/3ebf29a1-a116-9d17-5e9a-bad0d6c2d756') +('3ebf29a1-a116-9d17-5e9a-bad0d6c2d756', 'current', '51847-2', 'http://loinc.org', 'Evaluation + Plan note', None, None, datetime.date(2018, 7, 28), datetime.date(2018, 7, 28), datetime.date(2018, 7, 23), datetime.date(2018, 7, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/0b052286-9534-99a8-8d5e-06c2c04a7df7', 'Encounter/e5dabcb6-1d7a-7467-dbba-b864d0d5f5b0', 'DocumentReference/3ebf29a1-a116-9d17-5e9a-bad0d6c2d756') +('3f0e9271-a486-797d-978a-fb2d32d37d47', 'current', '34111-5', 'http://loinc.org', 'Emergency department note', None, None, datetime.date(2018, 6, 21), datetime.date(2018, 6, 21), datetime.date(2018, 6, 18), datetime.date(2018, 6, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/a46846ca-3f95-2cbb-3a9d-5eae150a0273', 'Encounter/5c3450fb-12f0-08f3-6e4d-8a5e433e19a4', 'DocumentReference/3f0e9271-a486-797d-978a-fb2d32d37d47') +('3f0e9271-a486-797d-978a-fb2d32d37d47', 'current', '51847-2', 'http://loinc.org', 'Evaluation + Plan note', None, None, datetime.date(2018, 6, 21), datetime.date(2018, 6, 21), datetime.date(2018, 6, 18), datetime.date(2018, 6, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/a46846ca-3f95-2cbb-3a9d-5eae150a0273', 'Encounter/5c3450fb-12f0-08f3-6e4d-8a5e433e19a4', 'DocumentReference/3f0e9271-a486-797d-978a-fb2d32d37d47') +('3f578a1b-f50a-9333-3030-306982950658', 'current', '34111-5', 'http://loinc.org', 'Emergency department note', None, None, datetime.date(2018, 6, 13), datetime.date(2018, 6, 13), datetime.date(2018, 6, 11), datetime.date(2018, 6, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/3cf7af45-2bee-aa9c-d524-40b487149d60', 'Encounter/d2782687-6885-037c-957d-579fbd681d2a', 'DocumentReference/3f578a1b-f50a-9333-3030-306982950658') +('3f578a1b-f50a-9333-3030-306982950658', 'current', '51847-2', 'http://loinc.org', 'Evaluation + Plan note', None, None, datetime.date(2018, 6, 13), datetime.date(2018, 6, 13), datetime.date(2018, 6, 11), datetime.date(2018, 6, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/3cf7af45-2bee-aa9c-d524-40b487149d60', 'Encounter/d2782687-6885-037c-957d-579fbd681d2a', 'DocumentReference/3f578a1b-f50a-9333-3030-306982950658') +('406679b2-a02c-0003-3b17-56ba373fccff', 'current', '34111-5', 'http://loinc.org', 'Emergency department note', None, None, datetime.date(2018, 7, 21), datetime.date(2018, 7, 21), datetime.date(2018, 7, 16), datetime.date(2018, 7, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/0734762a-9db6-22fc-b595-c3e472bb2a9a', 'Encounter/2f55edb9-a906-0b40-e183-89b1d65d1aa1', 'DocumentReference/406679b2-a02c-0003-3b17-56ba373fccff') +('406679b2-a02c-0003-3b17-56ba373fccff', 'current', '51847-2', 'http://loinc.org', 'Evaluation + Plan note', None, None, datetime.date(2018, 7, 21), datetime.date(2018, 7, 21), datetime.date(2018, 7, 16), datetime.date(2018, 7, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/0734762a-9db6-22fc-b595-c3e472bb2a9a', 'Encounter/2f55edb9-a906-0b40-e183-89b1d65d1aa1', 'DocumentReference/406679b2-a02c-0003-3b17-56ba373fccff') +('41eb62dd-7032-e98d-84c6-d494ad8c877b', 'current', '34111-5', 'http://loinc.org', 'Emergency department note', None, 'final', datetime.date(2018, 7, 31), datetime.date(2018, 7, 31), datetime.date(2018, 7, 30), datetime.date(2018, 7, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/2a0e1946-acf6-5a7e-9399-a9cbc4730199', 'Encounter/aabb3ac3-c4a3-f613-9507-63280adb9209', 'DocumentReference/41eb62dd-7032-e98d-84c6-d494ad8c877b') +('41eb62dd-7032-e98d-84c6-d494ad8c877b', 'current', '51847-2', 'http://loinc.org', 'Evaluation + Plan note', None, 'final', datetime.date(2018, 7, 31), datetime.date(2018, 7, 31), datetime.date(2018, 7, 30), datetime.date(2018, 7, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/2a0e1946-acf6-5a7e-9399-a9cbc4730199', 'Encounter/aabb3ac3-c4a3-f613-9507-63280adb9209', 'DocumentReference/41eb62dd-7032-e98d-84c6-d494ad8c877b') +('4390dbd1-3bdf-e516-9fe0-a8180181507f', 'current', '34111-5', 'http://loinc.org', 'Emergency department note', None, 'amended', datetime.date(2018, 6, 3), datetime.date(2018, 6, 3), datetime.date(2018, 5, 28), datetime.date(2018, 6, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/e80dda2c-a260-dbf7-3167-bf0945f3a91d', 'Encounter/029d1814-d7bf-0624-524d-7ccda5f320f6', 'DocumentReference/4390dbd1-3bdf-e516-9fe0-a8180181507f') +('4390dbd1-3bdf-e516-9fe0-a8180181507f', 'current', '51847-2', 'http://loinc.org', 'Evaluation + Plan note', None, 'amended', datetime.date(2018, 6, 3), datetime.date(2018, 6, 3), datetime.date(2018, 5, 28), datetime.date(2018, 6, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/e80dda2c-a260-dbf7-3167-bf0945f3a91d', 'Encounter/029d1814-d7bf-0624-524d-7ccda5f320f6', 'DocumentReference/4390dbd1-3bdf-e516-9fe0-a8180181507f') +('4390dbd1-3bdf-e516-9fe0-a8180181507f-error', 'current', '34111-5', 'http://loinc.org', 'Emergency department note', None, 'entered-in-error', datetime.date(2018, 6, 3), datetime.date(2018, 6, 3), datetime.date(2018, 5, 28), datetime.date(2018, 6, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/e80dda2c-a260-dbf7-3167-bf0945f3a91d', 'Encounter/029d1814-d7bf-0624-524d-7ccda5f320f6', 'DocumentReference/4390dbd1-3bdf-e516-9fe0-a8180181507f-error') +('4390dbd1-3bdf-e516-9fe0-a8180181507f-error', 'current', '51847-2', 'http://loinc.org', 'Evaluation + Plan note', None, 'entered-in-error', datetime.date(2018, 6, 3), datetime.date(2018, 6, 3), datetime.date(2018, 5, 28), datetime.date(2018, 6, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/e80dda2c-a260-dbf7-3167-bf0945f3a91d', 'Encounter/029d1814-d7bf-0624-524d-7ccda5f320f6', 'DocumentReference/4390dbd1-3bdf-e516-9fe0-a8180181507f-error') +('4439aa6e-fbc2-21a1-208e-095907104a65', 'current', '34111-5', 'http://loinc.org', 'Emergency department note', None, None, datetime.date(2018, 6, 30), datetime.date(2018, 6, 30), datetime.date(2018, 6, 25), datetime.date(2018, 6, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/82b8a670-4700-30e8-24a0-b83efa3c5e0a', 'Encounter/75b68644-535d-bdc1-4c31-aa9fe7e1822f', 'DocumentReference/4439aa6e-fbc2-21a1-208e-095907104a65') +('4439aa6e-fbc2-21a1-208e-095907104a65', 'current', '51847-2', 'http://loinc.org', 'Evaluation + Plan note', None, None, datetime.date(2018, 6, 30), datetime.date(2018, 6, 30), datetime.date(2018, 6, 25), datetime.date(2018, 6, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/82b8a670-4700-30e8-24a0-b83efa3c5e0a', 'Encounter/75b68644-535d-bdc1-4c31-aa9fe7e1822f', 'DocumentReference/4439aa6e-fbc2-21a1-208e-095907104a65') +('45160ef5-42e8-7239-6633-904308273198', 'current', '34111-5', 'http://loinc.org', 'Emergency department note', None, None, datetime.date(2018, 7, 13), datetime.date(2018, 7, 13), datetime.date(2018, 7, 9), datetime.date(2018, 7, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/3627adb8-f741-acf3-2dd6-10f3bcbe1077', 'Encounter/bca7cabc-b2fc-8a08-c69b-5bc0afa20d80', 'DocumentReference/45160ef5-42e8-7239-6633-904308273198') +('45160ef5-42e8-7239-6633-904308273198', 'current', '51847-2', 'http://loinc.org', 'Evaluation + Plan note', None, None, datetime.date(2018, 7, 13), datetime.date(2018, 7, 13), datetime.date(2018, 7, 9), datetime.date(2018, 7, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/3627adb8-f741-acf3-2dd6-10f3bcbe1077', 'Encounter/bca7cabc-b2fc-8a08-c69b-5bc0afa20d80', 'DocumentReference/45160ef5-42e8-7239-6633-904308273198') +('4711ca43-989d-a8f9-5f32-0102640804cf', 'current', '34111-5', 'http://loinc.org', 'Emergency department note', None, None, datetime.date(2018, 7, 19), datetime.date(2018, 7, 19), datetime.date(2018, 7, 16), datetime.date(2018, 7, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/d3c0274f-f42b-8d2b-15f2-82331e723383', 'Encounter/6565ef5c-30b9-8697-6ca6-2b77894d5437', 'DocumentReference/4711ca43-989d-a8f9-5f32-0102640804cf') +('4711ca43-989d-a8f9-5f32-0102640804cf', 'current', '51847-2', 'http://loinc.org', 'Evaluation + Plan note', None, None, datetime.date(2018, 7, 19), datetime.date(2018, 7, 19), datetime.date(2018, 7, 16), datetime.date(2018, 7, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/d3c0274f-f42b-8d2b-15f2-82331e723383', 'Encounter/6565ef5c-30b9-8697-6ca6-2b77894d5437', 'DocumentReference/4711ca43-989d-a8f9-5f32-0102640804cf') +('48693636-4eec-ad3d-b71d-8f650bd0a6f1', 'current', '34111-5', 'http://loinc.org', 'Emergency department note', None, None, datetime.date(2018, 6, 7), datetime.date(2018, 6, 7), datetime.date(2018, 6, 4), datetime.date(2018, 6, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/c7ad408d-fcae-b54a-eb1d-26d48f7a5f84', 'Encounter/02eb4e14-1a6f-d968-2c26-c0cf5023afe0', 'DocumentReference/48693636-4eec-ad3d-b71d-8f650bd0a6f1') +('48693636-4eec-ad3d-b71d-8f650bd0a6f1', 'current', '51847-2', 'http://loinc.org', 'Evaluation + Plan note', None, None, datetime.date(2018, 6, 7), datetime.date(2018, 6, 7), datetime.date(2018, 6, 4), datetime.date(2018, 6, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/c7ad408d-fcae-b54a-eb1d-26d48f7a5f84', 'Encounter/02eb4e14-1a6f-d968-2c26-c0cf5023afe0', 'DocumentReference/48693636-4eec-ad3d-b71d-8f650bd0a6f1') +('48933dd8-3fcf-416e-89ca-27851e45391f', 'current', '34111-5', 'http://loinc.org', 'Emergency department note', None, None, datetime.date(2018, 7, 29), datetime.date(2018, 7, 29), datetime.date(2018, 7, 23), datetime.date(2018, 7, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/7cef0e6f-9aea-4079-dfc6-18a96454708e', 'Encounter/d735c414-9dd3-c9b1-285c-8da79a7fbbdf', 'DocumentReference/48933dd8-3fcf-416e-89ca-27851e45391f') +('48933dd8-3fcf-416e-89ca-27851e45391f', 'current', '51847-2', 'http://loinc.org', 'Evaluation + Plan note', None, None, datetime.date(2018, 7, 29), datetime.date(2018, 7, 29), datetime.date(2018, 7, 23), datetime.date(2018, 7, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/7cef0e6f-9aea-4079-dfc6-18a96454708e', 'Encounter/d735c414-9dd3-c9b1-285c-8da79a7fbbdf', 'DocumentReference/48933dd8-3fcf-416e-89ca-27851e45391f') +('4b2e99d5-d4c2-fd1f-a5fd-96fe9546b58a', 'current', '34111-5', 'http://loinc.org', 'Emergency department note', None, None, datetime.date(2018, 7, 10), datetime.date(2018, 7, 10), datetime.date(2018, 7, 9), datetime.date(2018, 7, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/6385ddd7-2639-6505-3789-0521b8f66c8b', 'Encounter/fd0754a4-e96d-cba7-b3c0-77697a09c86e', 'DocumentReference/4b2e99d5-d4c2-fd1f-a5fd-96fe9546b58a') +('4b2e99d5-d4c2-fd1f-a5fd-96fe9546b58a', 'current', '51847-2', 'http://loinc.org', 'Evaluation + Plan note', None, None, datetime.date(2018, 7, 10), datetime.date(2018, 7, 10), datetime.date(2018, 7, 9), datetime.date(2018, 7, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/6385ddd7-2639-6505-3789-0521b8f66c8b', 'Encounter/fd0754a4-e96d-cba7-b3c0-77697a09c86e', 'DocumentReference/4b2e99d5-d4c2-fd1f-a5fd-96fe9546b58a') +('99b390f4-1bcb-21ec-85d5-85cbb74e86ae', 'current', '34111-5', 'http://loinc.org', 'Emergency department note', None, None, datetime.date(2018, 7, 13), datetime.date(2018, 7, 13), datetime.date(2018, 7, 9), datetime.date(2018, 7, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/9eaa056b-1efc-0cc8-70ff-62c8f704cc13', 'Encounter/5c994000-aa78-2be5-e6cf-99f230d50c2f', 'DocumentReference/99b390f4-1bcb-21ec-85d5-85cbb74e86ae') +('99b390f4-1bcb-21ec-85d5-85cbb74e86ae', 'current', '51847-2', 'http://loinc.org', 'Evaluation + Plan note', None, None, datetime.date(2018, 7, 13), datetime.date(2018, 7, 13), datetime.date(2018, 7, 9), datetime.date(2018, 7, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/9eaa056b-1efc-0cc8-70ff-62c8f704cc13', 'Encounter/5c994000-aa78-2be5-e6cf-99f230d50c2f', 'DocumentReference/99b390f4-1bcb-21ec-85d5-85cbb74e86ae') +('99d49a34-c515-23a1-c3e4-ef73c3cef727', 'current', '34111-5', 'http://loinc.org', 'Emergency department note', None, None, datetime.date(2018, 7, 26), datetime.date(2018, 7, 26), datetime.date(2018, 7, 23), datetime.date(2018, 7, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/cc9fb8e2-fe52-b72a-aebb-9d10260f121b', 'Encounter/683b04eb-663a-849f-715f-4ccd70bf1524', 'DocumentReference/99d49a34-c515-23a1-c3e4-ef73c3cef727') +('99d49a34-c515-23a1-c3e4-ef73c3cef727', 'current', '51847-2', 'http://loinc.org', 'Evaluation + Plan note', None, None, datetime.date(2018, 7, 26), datetime.date(2018, 7, 26), datetime.date(2018, 7, 23), datetime.date(2018, 7, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/cc9fb8e2-fe52-b72a-aebb-9d10260f121b', 'Encounter/683b04eb-663a-849f-715f-4ccd70bf1524', 'DocumentReference/99d49a34-c515-23a1-c3e4-ef73c3cef727') +('99e26f8b-a5a2-ad5e-713a-16266b5991a1', 'current', '34111-5', 'http://loinc.org', 'Emergency department note', None, None, datetime.date(2018, 6, 29), datetime.date(2018, 6, 29), datetime.date(2018, 6, 25), datetime.date(2018, 6, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/1c498b42-61fd-6341-69c3-053f6e4fe404', 'Encounter/e613f29d-7505-6f2e-a1f5-bfbec300752d', 'DocumentReference/99e26f8b-a5a2-ad5e-713a-16266b5991a1') +('99e26f8b-a5a2-ad5e-713a-16266b5991a1', 'current', '51847-2', 'http://loinc.org', 'Evaluation + Plan note', None, None, datetime.date(2018, 6, 29), datetime.date(2018, 6, 29), datetime.date(2018, 6, 25), datetime.date(2018, 6, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/1c498b42-61fd-6341-69c3-053f6e4fe404', 'Encounter/e613f29d-7505-6f2e-a1f5-bfbec300752d', 'DocumentReference/99e26f8b-a5a2-ad5e-713a-16266b5991a1') +('9a50a40a-8099-5ab5-0903-1ba65d8c0905', 'current', '34111-5', 'http://loinc.org', 'Emergency department note', None, None, datetime.date(2018, 6, 14), datetime.date(2018, 6, 14), datetime.date(2018, 6, 11), datetime.date(2018, 6, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/24906e2c-e556-71dc-23d9-3e1d5fb08986', 'Encounter/1154d05c-8727-9373-4224-25b9fdba9ab3', 'DocumentReference/9a50a40a-8099-5ab5-0903-1ba65d8c0905') +('9a50a40a-8099-5ab5-0903-1ba65d8c0905', 'current', '51847-2', 'http://loinc.org', 'Evaluation + Plan note', None, None, datetime.date(2018, 6, 14), datetime.date(2018, 6, 14), datetime.date(2018, 6, 11), datetime.date(2018, 6, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/24906e2c-e556-71dc-23d9-3e1d5fb08986', 'Encounter/1154d05c-8727-9373-4224-25b9fdba9ab3', 'DocumentReference/9a50a40a-8099-5ab5-0903-1ba65d8c0905') +('9ca118c6-e354-5588-3cdc-77ee3b3c8711', 'current', '34111-5', 'http://loinc.org', 'Emergency department note', None, None, datetime.date(2018, 7, 28), datetime.date(2018, 7, 28), datetime.date(2018, 7, 23), datetime.date(2018, 7, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/2da1bee2-2bc2-4511-84e1-42860310e2fb', 'Encounter/d5f342b7-017c-f2e7-8697-5a038c91518e', 'DocumentReference/9ca118c6-e354-5588-3cdc-77ee3b3c8711') +('9ca118c6-e354-5588-3cdc-77ee3b3c8711', 'current', '51847-2', 'http://loinc.org', 'Evaluation + Plan note', None, None, datetime.date(2018, 7, 28), datetime.date(2018, 7, 28), datetime.date(2018, 7, 23), datetime.date(2018, 7, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/2da1bee2-2bc2-4511-84e1-42860310e2fb', 'Encounter/d5f342b7-017c-f2e7-8697-5a038c91518e', 'DocumentReference/9ca118c6-e354-5588-3cdc-77ee3b3c8711') +('a1b69e45-11f8-a49f-170e-32004c70e842', 'current', '34111-5', 'http://loinc.org', 'Emergency department note', None, None, datetime.date(2018, 7, 11), datetime.date(2018, 7, 11), datetime.date(2018, 7, 9), datetime.date(2018, 7, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/5ce2e599-fb6e-9b4d-3c2e-87310619b957', 'Encounter/4b03a408-6694-88e3-0e63-3ee464ecd6cd', 'DocumentReference/a1b69e45-11f8-a49f-170e-32004c70e842') +('a1b69e45-11f8-a49f-170e-32004c70e842', 'current', '51847-2', 'http://loinc.org', 'Evaluation + Plan note', None, None, datetime.date(2018, 7, 11), datetime.date(2018, 7, 11), datetime.date(2018, 7, 9), datetime.date(2018, 7, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/5ce2e599-fb6e-9b4d-3c2e-87310619b957', 'Encounter/4b03a408-6694-88e3-0e63-3ee464ecd6cd', 'DocumentReference/a1b69e45-11f8-a49f-170e-32004c70e842') +('a3964c82-0605-c2b2-97dc-0de17a1ec0ef', 'current', '34111-5', 'http://loinc.org', 'Emergency department note', None, None, datetime.date(2018, 6, 17), datetime.date(2018, 6, 17), datetime.date(2018, 6, 11), datetime.date(2018, 6, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/7f941bcc-e7b2-99e1-585f-129d0ef1c13d', 'Encounter/65f8fdca-a949-80a0-8072-094e9aaee474', 'DocumentReference/a3964c82-0605-c2b2-97dc-0de17a1ec0ef') +('a3964c82-0605-c2b2-97dc-0de17a1ec0ef', 'current', '51847-2', 'http://loinc.org', 'Evaluation + Plan note', None, None, datetime.date(2018, 6, 17), datetime.date(2018, 6, 17), datetime.date(2018, 6, 11), datetime.date(2018, 6, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/7f941bcc-e7b2-99e1-585f-129d0ef1c13d', 'Encounter/65f8fdca-a949-80a0-8072-094e9aaee474', 'DocumentReference/a3964c82-0605-c2b2-97dc-0de17a1ec0ef') +('a5231f35-ad14-580e-1888-55c1b383aa11', 'current', '34111-5', 'http://loinc.org', 'Emergency department note', None, None, datetime.date(2018, 7, 2), datetime.date(2018, 7, 2), datetime.date(2018, 7, 2), datetime.date(2018, 7, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/3ae095ec-8fe0-133b-36d4-8785a6ad8df3', 'Encounter/75312bd2-d5ac-c62e-c9df-0004783725c7', 'DocumentReference/a5231f35-ad14-580e-1888-55c1b383aa11') +('a5231f35-ad14-580e-1888-55c1b383aa11', 'current', '51847-2', 'http://loinc.org', 'Evaluation + Plan note', None, None, datetime.date(2018, 7, 2), datetime.date(2018, 7, 2), datetime.date(2018, 7, 2), datetime.date(2018, 7, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/3ae095ec-8fe0-133b-36d4-8785a6ad8df3', 'Encounter/75312bd2-d5ac-c62e-c9df-0004783725c7', 'DocumentReference/a5231f35-ad14-580e-1888-55c1b383aa11') +('a59ca653-b95d-09d2-9fa5-a1b492d85a5f', 'current', '34111-5', 'http://loinc.org', 'Emergency department note', None, None, datetime.date(2018, 6, 28), datetime.date(2018, 6, 28), datetime.date(2018, 6, 25), datetime.date(2018, 6, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/c20e5afd-30df-ac3d-6684-cc29438a9bc4', 'Encounter/b864bcd8-14e0-8bec-b7cc-f8629d91470e', 'DocumentReference/a59ca653-b95d-09d2-9fa5-a1b492d85a5f') +('a59ca653-b95d-09d2-9fa5-a1b492d85a5f', 'current', '51847-2', 'http://loinc.org', 'Evaluation + Plan note', None, None, datetime.date(2018, 6, 28), datetime.date(2018, 6, 28), datetime.date(2018, 6, 25), datetime.date(2018, 6, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/c20e5afd-30df-ac3d-6684-cc29438a9bc4', 'Encounter/b864bcd8-14e0-8bec-b7cc-f8629d91470e', 'DocumentReference/a59ca653-b95d-09d2-9fa5-a1b492d85a5f') +('a69150c5-2fbe-2284-1eb5-e11146858a22', 'current', '34111-5', 'http://loinc.org', 'Emergency department note', None, None, datetime.date(2018, 6, 1), datetime.date(2018, 6, 1), datetime.date(2018, 5, 28), datetime.date(2018, 6, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/9c8d8539-0b1e-73e2-b64f-83f1ea601fa4', 'Encounter/f2752dd7-1bf1-739d-dd8c-40122d0b63bc', 'DocumentReference/a69150c5-2fbe-2284-1eb5-e11146858a22') +('a69150c5-2fbe-2284-1eb5-e11146858a22', 'current', '51847-2', 'http://loinc.org', 'Evaluation + Plan note', None, None, datetime.date(2018, 6, 1), datetime.date(2018, 6, 1), datetime.date(2018, 5, 28), datetime.date(2018, 6, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/9c8d8539-0b1e-73e2-b64f-83f1ea601fa4', 'Encounter/f2752dd7-1bf1-739d-dd8c-40122d0b63bc', 'DocumentReference/a69150c5-2fbe-2284-1eb5-e11146858a22') +('a7115116-f8da-3960-e3ed-f1f0d89646c3', 'current', '34111-5', 'http://loinc.org', 'Emergency department note', None, None, datetime.date(2018, 6, 2), datetime.date(2018, 6, 2), datetime.date(2018, 5, 28), datetime.date(2018, 6, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/8877ef1f-7cd7-3242-d7f0-73cf3f7165f4', 'Encounter/299b6495-3fe7-8db3-c494-6e1ce8b7986d', 'DocumentReference/a7115116-f8da-3960-e3ed-f1f0d89646c3') +('a7115116-f8da-3960-e3ed-f1f0d89646c3', 'current', '51847-2', 'http://loinc.org', 'Evaluation + Plan note', None, None, datetime.date(2018, 6, 2), datetime.date(2018, 6, 2), datetime.date(2018, 5, 28), datetime.date(2018, 6, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/8877ef1f-7cd7-3242-d7f0-73cf3f7165f4', 'Encounter/299b6495-3fe7-8db3-c494-6e1ce8b7986d', 'DocumentReference/a7115116-f8da-3960-e3ed-f1f0d89646c3') +('a79da4dd-83bc-5b6a-db34-bd35b3acbd2c', 'current', '34111-5', 'http://loinc.org', 'Emergency department note', None, None, datetime.date(2018, 6, 6), datetime.date(2018, 6, 6), datetime.date(2018, 6, 4), datetime.date(2018, 6, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/19158de4-66a2-f70f-e3bf-4396b312c8f1', 'Encounter/ed151e04-3dd6-8cb7-a3e5-777c8a8667f1', 'DocumentReference/a79da4dd-83bc-5b6a-db34-bd35b3acbd2c') +('a79da4dd-83bc-5b6a-db34-bd35b3acbd2c', 'current', '51847-2', 'http://loinc.org', 'Evaluation + Plan note', None, None, datetime.date(2018, 6, 6), datetime.date(2018, 6, 6), datetime.date(2018, 6, 4), datetime.date(2018, 6, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/19158de4-66a2-f70f-e3bf-4396b312c8f1', 'Encounter/ed151e04-3dd6-8cb7-a3e5-777c8a8667f1', 'DocumentReference/a79da4dd-83bc-5b6a-db34-bd35b3acbd2c') +('a95df5ea-7005-9e98-e97a-1ade6967b585', 'current', '34111-5', 'http://loinc.org', 'Emergency department note', None, None, datetime.date(2018, 6, 16), datetime.date(2018, 6, 16), datetime.date(2018, 6, 11), datetime.date(2018, 6, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/16be855b-ece2-8b96-1ef9-a4d93adf3289', 'Encounter/83d0d564-3bbf-48eb-7445-bd2b81130671', 'DocumentReference/a95df5ea-7005-9e98-e97a-1ade6967b585') +('a95df5ea-7005-9e98-e97a-1ade6967b585', 'current', '51847-2', 'http://loinc.org', 'Evaluation + Plan note', None, None, datetime.date(2018, 6, 16), datetime.date(2018, 6, 16), datetime.date(2018, 6, 11), datetime.date(2018, 6, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/16be855b-ece2-8b96-1ef9-a4d93adf3289', 'Encounter/83d0d564-3bbf-48eb-7445-bd2b81130671', 'DocumentReference/a95df5ea-7005-9e98-e97a-1ade6967b585') +('a96ba3b7-a461-5849-1881-d372e0460ccc', 'current', '34111-5', 'http://loinc.org', 'Emergency department note', None, None, datetime.date(2018, 7, 14), datetime.date(2018, 7, 14), datetime.date(2018, 7, 9), datetime.date(2018, 7, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/26a3984f-b2a8-e67f-7abc-ff147a0e6e35', 'Encounter/79d8f213-7847-646b-8a66-5da208cc1c27', 'DocumentReference/a96ba3b7-a461-5849-1881-d372e0460ccc') +('a96ba3b7-a461-5849-1881-d372e0460ccc', 'current', '51847-2', 'http://loinc.org', 'Evaluation + Plan note', None, None, datetime.date(2018, 7, 14), datetime.date(2018, 7, 14), datetime.date(2018, 7, 9), datetime.date(2018, 7, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/26a3984f-b2a8-e67f-7abc-ff147a0e6e35', 'Encounter/79d8f213-7847-646b-8a66-5da208cc1c27', 'DocumentReference/a96ba3b7-a461-5849-1881-d372e0460ccc') +('ac0439bc-e450-d339-da6d-5ead96d8b346', 'current', '34111-5', 'http://loinc.org', 'Emergency department note', None, None, datetime.date(2018, 7, 30), datetime.date(2018, 7, 30), datetime.date(2018, 7, 30), datetime.date(2018, 7, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/2858705f-5af1-9869-4d94-894e09a9f99a', 'Encounter/de9d67de-6ae3-32f7-20f2-e719ae23a9a3', 'DocumentReference/ac0439bc-e450-d339-da6d-5ead96d8b346') +('ac0439bc-e450-d339-da6d-5ead96d8b346', 'current', '51847-2', 'http://loinc.org', 'Evaluation + Plan note', None, None, datetime.date(2018, 7, 30), datetime.date(2018, 7, 30), datetime.date(2018, 7, 30), datetime.date(2018, 7, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/2858705f-5af1-9869-4d94-894e09a9f99a', 'Encounter/de9d67de-6ae3-32f7-20f2-e719ae23a9a3', 'DocumentReference/ac0439bc-e450-d339-da6d-5ead96d8b346') +('ad2bee76-6e59-5d8b-21ed-b30cdb784198', 'current', '34111-5', 'http://loinc.org', 'Emergency department note', None, None, datetime.date(2018, 7, 9), datetime.date(2018, 7, 9), datetime.date(2018, 7, 9), datetime.date(2018, 7, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/e455ca3f-fc16-6ffc-297a-adc27e2db183', 'Encounter/98d4bd14-d78e-debb-e7dc-2df7786aedf3', 'DocumentReference/ad2bee76-6e59-5d8b-21ed-b30cdb784198') +('ad2bee76-6e59-5d8b-21ed-b30cdb784198', 'current', '51847-2', 'http://loinc.org', 'Evaluation + Plan note', None, None, datetime.date(2018, 7, 9), datetime.date(2018, 7, 9), datetime.date(2018, 7, 9), datetime.date(2018, 7, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/e455ca3f-fc16-6ffc-297a-adc27e2db183', 'Encounter/98d4bd14-d78e-debb-e7dc-2df7786aedf3', 'DocumentReference/ad2bee76-6e59-5d8b-21ed-b30cdb784198') +('b1f5c114-8e28-08c0-0193-0855aa10c97f', 'current', '34111-5', 'http://loinc.org', 'Emergency department note', None, None, datetime.date(2018, 7, 2), datetime.date(2018, 7, 2), datetime.date(2018, 7, 2), datetime.date(2018, 7, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/c7c5c028-f1fb-962b-8db2-dfd4c6d6b02a', 'Encounter/aa890974-162f-5906-dc71-2bb6d2185314', 'DocumentReference/b1f5c114-8e28-08c0-0193-0855aa10c97f') +('b1f5c114-8e28-08c0-0193-0855aa10c97f', 'current', '51847-2', 'http://loinc.org', 'Evaluation + Plan note', None, None, datetime.date(2018, 7, 2), datetime.date(2018, 7, 2), datetime.date(2018, 7, 2), datetime.date(2018, 7, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/c7c5c028-f1fb-962b-8db2-dfd4c6d6b02a', 'Encounter/aa890974-162f-5906-dc71-2bb6d2185314', 'DocumentReference/b1f5c114-8e28-08c0-0193-0855aa10c97f') +('b2896621-57ef-1ad3-91c5-389dce96973b', 'current', '34111-5', 'http://loinc.org', 'Emergency department note', None, None, datetime.date(2018, 7, 7), datetime.date(2018, 7, 7), datetime.date(2018, 7, 2), datetime.date(2018, 7, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/ac91b90d-97e4-4fc5-41cd-036bac49e6e8', 'Encounter/dc5ed645-3979-e765-3e03-6ba2173027c3', 'DocumentReference/b2896621-57ef-1ad3-91c5-389dce96973b') +('b2896621-57ef-1ad3-91c5-389dce96973b', 'current', '51847-2', 'http://loinc.org', 'Evaluation + Plan note', None, None, datetime.date(2018, 7, 7), datetime.date(2018, 7, 7), datetime.date(2018, 7, 2), datetime.date(2018, 7, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/ac91b90d-97e4-4fc5-41cd-036bac49e6e8', 'Encounter/dc5ed645-3979-e765-3e03-6ba2173027c3', 'DocumentReference/b2896621-57ef-1ad3-91c5-389dce96973b') +('b3357397-9f4c-7d00-06af-18f03c63d583', 'current', '34111-5', 'http://loinc.org', 'Emergency department note', None, None, datetime.date(2018, 7, 15), datetime.date(2018, 7, 15), datetime.date(2018, 7, 9), datetime.date(2018, 7, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/c1bfec36-dc2c-afc8-c767-3d35ed2bf6f0', 'Encounter/8ff1dc01-5a28-b2d8-3b42-4b7a7d539970', 'DocumentReference/b3357397-9f4c-7d00-06af-18f03c63d583') +('b3357397-9f4c-7d00-06af-18f03c63d583', 'current', '51847-2', 'http://loinc.org', 'Evaluation + Plan note', None, None, datetime.date(2018, 7, 15), datetime.date(2018, 7, 15), datetime.date(2018, 7, 9), datetime.date(2018, 7, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/c1bfec36-dc2c-afc8-c767-3d35ed2bf6f0', 'Encounter/8ff1dc01-5a28-b2d8-3b42-4b7a7d539970', 'DocumentReference/b3357397-9f4c-7d00-06af-18f03c63d583') +('b339c2e8-35eb-1838-7eea-5a04c81695df', 'current', '34111-5', 'http://loinc.org', 'Emergency department note', None, None, datetime.date(2018, 6, 14), datetime.date(2018, 6, 14), datetime.date(2018, 6, 11), datetime.date(2018, 6, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/267fc42d-cd9e-8527-1f9e-887fe7776147', 'Encounter/4c4d0730-201f-5b75-c657-8d0de09cc28f', 'DocumentReference/b339c2e8-35eb-1838-7eea-5a04c81695df') +('b339c2e8-35eb-1838-7eea-5a04c81695df', 'current', '51847-2', 'http://loinc.org', 'Evaluation + Plan note', None, None, datetime.date(2018, 6, 14), datetime.date(2018, 6, 14), datetime.date(2018, 6, 11), datetime.date(2018, 6, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/267fc42d-cd9e-8527-1f9e-887fe7776147', 'Encounter/4c4d0730-201f-5b75-c657-8d0de09cc28f', 'DocumentReference/b339c2e8-35eb-1838-7eea-5a04c81695df') +('b39532e8-ee15-a7c4-cac5-353a8be67d15', 'current', '34111-5', 'http://loinc.org', 'Emergency department note', None, None, datetime.date(2018, 6, 8), datetime.date(2018, 6, 8), datetime.date(2018, 6, 4), datetime.date(2018, 6, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/6a883108-7b87-120b-d163-d369336e04e5', 'Encounter/2b1ee164-6c87-420d-a9e2-6c235ebeef71', 'DocumentReference/b39532e8-ee15-a7c4-cac5-353a8be67d15') +('b39532e8-ee15-a7c4-cac5-353a8be67d15', 'current', '51847-2', 'http://loinc.org', 'Evaluation + Plan note', None, None, datetime.date(2018, 6, 8), datetime.date(2018, 6, 8), datetime.date(2018, 6, 4), datetime.date(2018, 6, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/6a883108-7b87-120b-d163-d369336e04e5', 'Encounter/2b1ee164-6c87-420d-a9e2-6c235ebeef71', 'DocumentReference/b39532e8-ee15-a7c4-cac5-353a8be67d15') +('b44d277c-7c09-a39b-97e9-1e96d71b6978', 'current', '34111-5', 'http://loinc.org', 'Emergency department note', None, None, datetime.date(2018, 6, 15), datetime.date(2018, 6, 15), datetime.date(2018, 6, 11), datetime.date(2018, 6, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/7bf52d54-0d2a-265a-15aa-eeed7aaf4af6', 'Encounter/ba84689e-2f9f-7cea-af1f-d69ffdd3a3eb', 'DocumentReference/b44d277c-7c09-a39b-97e9-1e96d71b6978') +('b44d277c-7c09-a39b-97e9-1e96d71b6978', 'current', '51847-2', 'http://loinc.org', 'Evaluation + Plan note', None, None, datetime.date(2018, 6, 15), datetime.date(2018, 6, 15), datetime.date(2018, 6, 11), datetime.date(2018, 6, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/7bf52d54-0d2a-265a-15aa-eeed7aaf4af6', 'Encounter/ba84689e-2f9f-7cea-af1f-d69ffdd3a3eb', 'DocumentReference/b44d277c-7c09-a39b-97e9-1e96d71b6978') +('b58f7768-64be-6c0f-1b82-3deffdef1076', 'current', '34111-5', 'http://loinc.org', 'Emergency department note', None, None, datetime.date(2018, 6, 29), datetime.date(2018, 6, 29), datetime.date(2018, 6, 25), datetime.date(2018, 6, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/a28be3e1-a6bd-7df4-fc81-1140848f8453', 'Encounter/91f94a9d-69a7-e30a-cd1a-68c52dc01e70', 'DocumentReference/b58f7768-64be-6c0f-1b82-3deffdef1076') +('b58f7768-64be-6c0f-1b82-3deffdef1076', 'current', '51847-2', 'http://loinc.org', 'Evaluation + Plan note', None, None, datetime.date(2018, 6, 29), datetime.date(2018, 6, 29), datetime.date(2018, 6, 25), datetime.date(2018, 6, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/a28be3e1-a6bd-7df4-fc81-1140848f8453', 'Encounter/91f94a9d-69a7-e30a-cd1a-68c52dc01e70', 'DocumentReference/b58f7768-64be-6c0f-1b82-3deffdef1076') +('b73493d0-e2f4-9aa6-cdad-920f7c126d6c', 'current', '34111-5', 'http://loinc.org', 'Emergency department note', None, None, datetime.date(2018, 7, 16), datetime.date(2018, 7, 16), datetime.date(2018, 7, 16), datetime.date(2018, 7, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/50f8b42e-17a6-e932-8546-da94004c597c', 'Encounter/37604257-be1a-120f-81ee-336f81603f92', 'DocumentReference/b73493d0-e2f4-9aa6-cdad-920f7c126d6c') +('b73493d0-e2f4-9aa6-cdad-920f7c126d6c', 'current', '51847-2', 'http://loinc.org', 'Evaluation + Plan note', None, None, datetime.date(2018, 7, 16), datetime.date(2018, 7, 16), datetime.date(2018, 7, 16), datetime.date(2018, 7, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/50f8b42e-17a6-e932-8546-da94004c597c', 'Encounter/37604257-be1a-120f-81ee-336f81603f92', 'DocumentReference/b73493d0-e2f4-9aa6-cdad-920f7c126d6c') +('b7b68006-53d5-b823-d193-56b262f45e8b', 'current', '34111-5', 'http://loinc.org', 'Emergency department note', None, None, datetime.date(2018, 7, 19), datetime.date(2018, 7, 19), datetime.date(2018, 7, 16), datetime.date(2018, 7, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/ad3ed58a-5645-af0a-eeca-ab543123a8aa', 'Encounter/03e34b19-2889-b828-792d-2a83400c55be', 'DocumentReference/b7b68006-53d5-b823-d193-56b262f45e8b') +('b7b68006-53d5-b823-d193-56b262f45e8b', 'current', '51847-2', 'http://loinc.org', 'Evaluation + Plan note', None, None, datetime.date(2018, 7, 19), datetime.date(2018, 7, 19), datetime.date(2018, 7, 16), datetime.date(2018, 7, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/ad3ed58a-5645-af0a-eeca-ab543123a8aa', 'Encounter/03e34b19-2889-b828-792d-2a83400c55be', 'DocumentReference/b7b68006-53d5-b823-d193-56b262f45e8b') +('b953a85f-f18b-d7a3-8974-ba44e0a3141c', 'current', '34111-5', 'http://loinc.org', 'Emergency department note', None, None, datetime.date(2018, 6, 5), datetime.date(2018, 6, 5), datetime.date(2018, 6, 4), datetime.date(2018, 6, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/a5bc08ea-9462-c4f5-1bd2-ff342598ac99', 'Encounter/f964be66-3fcd-95c8-0021-71c7d24c91b7', 'DocumentReference/b953a85f-f18b-d7a3-8974-ba44e0a3141c') +('b953a85f-f18b-d7a3-8974-ba44e0a3141c', 'current', '51847-2', 'http://loinc.org', 'Evaluation + Plan note', None, None, datetime.date(2018, 6, 5), datetime.date(2018, 6, 5), datetime.date(2018, 6, 4), datetime.date(2018, 6, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/a5bc08ea-9462-c4f5-1bd2-ff342598ac99', 'Encounter/f964be66-3fcd-95c8-0021-71c7d24c91b7', 'DocumentReference/b953a85f-f18b-d7a3-8974-ba44e0a3141c') +('b985a70c-9504-b7b3-0707-f8381ba77976', 'current', '34111-5', 'http://loinc.org', 'Emergency department note', None, None, datetime.date(2018, 6, 7), datetime.date(2018, 6, 7), datetime.date(2018, 6, 4), datetime.date(2018, 6, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/149de67a-2809-59a8-bfa2-36df509021dc', 'Encounter/beb26500-4ccd-ce0a-44f6-74f44be5fafe', 'DocumentReference/b985a70c-9504-b7b3-0707-f8381ba77976') +('b985a70c-9504-b7b3-0707-f8381ba77976', 'current', '51847-2', 'http://loinc.org', 'Evaluation + Plan note', None, None, datetime.date(2018, 6, 7), datetime.date(2018, 6, 7), datetime.date(2018, 6, 4), datetime.date(2018, 6, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/149de67a-2809-59a8-bfa2-36df509021dc', 'Encounter/beb26500-4ccd-ce0a-44f6-74f44be5fafe', 'DocumentReference/b985a70c-9504-b7b3-0707-f8381ba77976') +('ba0abbd6-49a9-95fa-2396-7118c56da8c6', 'current', '34111-5', 'http://loinc.org', 'Emergency department note', None, None, datetime.date(2018, 6, 12), datetime.date(2018, 6, 12), datetime.date(2018, 6, 11), datetime.date(2018, 6, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/9b17654f-a902-3d56-9000-4ade3dd3059f', 'Encounter/ca45bbef-ef2a-3b3c-ea5e-76bcd5865780', 'DocumentReference/ba0abbd6-49a9-95fa-2396-7118c56da8c6') +('ba0abbd6-49a9-95fa-2396-7118c56da8c6', 'current', '51847-2', 'http://loinc.org', 'Evaluation + Plan note', None, None, datetime.date(2018, 6, 12), datetime.date(2018, 6, 12), datetime.date(2018, 6, 11), datetime.date(2018, 6, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/9b17654f-a902-3d56-9000-4ade3dd3059f', 'Encounter/ca45bbef-ef2a-3b3c-ea5e-76bcd5865780', 'DocumentReference/ba0abbd6-49a9-95fa-2396-7118c56da8c6') +('bcbaa9d3-d7cf-3f5f-44d3-32c8a267f991', 'current', '34111-5', 'http://loinc.org', 'Emergency department note', None, None, datetime.date(2018, 7, 2), datetime.date(2018, 7, 2), datetime.date(2018, 7, 2), datetime.date(2018, 7, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/17fde357-dcc9-af8b-a8d3-4bd213afeb22', 'Encounter/32d0ae2d-1be8-9e90-a4da-4c222abd88a9', 'DocumentReference/bcbaa9d3-d7cf-3f5f-44d3-32c8a267f991') +('bcbaa9d3-d7cf-3f5f-44d3-32c8a267f991', 'current', '51847-2', 'http://loinc.org', 'Evaluation + Plan note', None, None, datetime.date(2018, 7, 2), datetime.date(2018, 7, 2), datetime.date(2018, 7, 2), datetime.date(2018, 7, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/17fde357-dcc9-af8b-a8d3-4bd213afeb22', 'Encounter/32d0ae2d-1be8-9e90-a4da-4c222abd88a9', 'DocumentReference/bcbaa9d3-d7cf-3f5f-44d3-32c8a267f991') +('bd60a52b-65b9-f26d-03e4-282850509f03', 'current', '34111-5', 'http://loinc.org', 'Emergency department note', None, None, datetime.date(2018, 7, 10), datetime.date(2018, 7, 10), datetime.date(2018, 7, 9), datetime.date(2018, 7, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/51032f44-d514-26e9-3e85-e956561c076e', 'Encounter/d73ed087-e0ae-78e0-7a05-1bac1060c476', 'DocumentReference/bd60a52b-65b9-f26d-03e4-282850509f03') +('bd60a52b-65b9-f26d-03e4-282850509f03', 'current', '51847-2', 'http://loinc.org', 'Evaluation + Plan note', None, None, datetime.date(2018, 7, 10), datetime.date(2018, 7, 10), datetime.date(2018, 7, 9), datetime.date(2018, 7, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/51032f44-d514-26e9-3e85-e956561c076e', 'Encounter/d73ed087-e0ae-78e0-7a05-1bac1060c476', 'DocumentReference/bd60a52b-65b9-f26d-03e4-282850509f03') +('bfddb0ff-1296-107e-76ca-14b4a14db9ce', 'current', '34111-5', 'http://loinc.org', 'Emergency department note', None, None, datetime.date(2018, 7, 2), datetime.date(2018, 7, 2), datetime.date(2018, 7, 2), datetime.date(2018, 7, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/26baae20-c8c5-003a-ab6b-ebcc49be20db', 'Encounter/c6ec2350-43d4-abab-2e84-4d2aadb337a7', 'DocumentReference/bfddb0ff-1296-107e-76ca-14b4a14db9ce') +('bfddb0ff-1296-107e-76ca-14b4a14db9ce', 'current', '51847-2', 'http://loinc.org', 'Evaluation + Plan note', None, None, datetime.date(2018, 7, 2), datetime.date(2018, 7, 2), datetime.date(2018, 7, 2), datetime.date(2018, 7, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/26baae20-c8c5-003a-ab6b-ebcc49be20db', 'Encounter/c6ec2350-43d4-abab-2e84-4d2aadb337a7', 'DocumentReference/bfddb0ff-1296-107e-76ca-14b4a14db9ce') +('c18dbe84-be31-cee5-1f2e-cf163cdd3e3f', 'current', '34111-5', 'http://loinc.org', 'Emergency department note', None, None, datetime.date(2018, 7, 27), datetime.date(2018, 7, 27), datetime.date(2018, 7, 23), datetime.date(2018, 7, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/a5b171a7-9b28-20e7-86a7-936ecbf55f36', 'Encounter/c4605953-3103-ede6-e0c0-e0588e6f019e', 'DocumentReference/c18dbe84-be31-cee5-1f2e-cf163cdd3e3f') +('c18dbe84-be31-cee5-1f2e-cf163cdd3e3f', 'current', '51847-2', 'http://loinc.org', 'Evaluation + Plan note', None, None, datetime.date(2018, 7, 27), datetime.date(2018, 7, 27), datetime.date(2018, 7, 23), datetime.date(2018, 7, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/a5b171a7-9b28-20e7-86a7-936ecbf55f36', 'Encounter/c4605953-3103-ede6-e0c0-e0588e6f019e', 'DocumentReference/c18dbe84-be31-cee5-1f2e-cf163cdd3e3f') +('c6598486-8276-b44a-286e-b376143f7efc', 'current', '34111-5', 'http://loinc.org', 'Emergency department note', None, None, datetime.date(2018, 6, 25), datetime.date(2018, 6, 25), datetime.date(2018, 6, 25), datetime.date(2018, 6, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/47c37c92-5932-9cfe-66be-208556780fe0', 'Encounter/b5974881-ae62-ddd6-b905-8c86c1ca9e33', 'DocumentReference/c6598486-8276-b44a-286e-b376143f7efc') +('c6598486-8276-b44a-286e-b376143f7efc', 'current', '51847-2', 'http://loinc.org', 'Evaluation + Plan note', None, None, datetime.date(2018, 6, 25), datetime.date(2018, 6, 25), datetime.date(2018, 6, 25), datetime.date(2018, 6, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/47c37c92-5932-9cfe-66be-208556780fe0', 'Encounter/b5974881-ae62-ddd6-b905-8c86c1ca9e33', 'DocumentReference/c6598486-8276-b44a-286e-b376143f7efc') +('c6c64129-9dfa-840d-3309-a5590cc74f2e', 'current', '34111-5', 'http://loinc.org', 'Emergency department note', None, None, datetime.date(2018, 6, 15), datetime.date(2018, 6, 15), datetime.date(2018, 6, 11), datetime.date(2018, 6, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/ad239efc-637c-e428-c829-b87e700d5446', 'Encounter/366df7d3-2ea9-db22-7cdd-60fa8a5c45ca', 'DocumentReference/c6c64129-9dfa-840d-3309-a5590cc74f2e') +('c6c64129-9dfa-840d-3309-a5590cc74f2e', 'current', '51847-2', 'http://loinc.org', 'Evaluation + Plan note', None, None, datetime.date(2018, 6, 15), datetime.date(2018, 6, 15), datetime.date(2018, 6, 11), datetime.date(2018, 6, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/ad239efc-637c-e428-c829-b87e700d5446', 'Encounter/366df7d3-2ea9-db22-7cdd-60fa8a5c45ca', 'DocumentReference/c6c64129-9dfa-840d-3309-a5590cc74f2e') +('c84e67e9-4ea8-700b-9f2b-c0179e803d4f', 'current', '34111-5', 'http://loinc.org', 'Emergency department note', None, None, datetime.date(2018, 7, 15), datetime.date(2018, 7, 15), datetime.date(2018, 7, 9), datetime.date(2018, 7, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/dffa62dc-8ec2-1cd6-ee75-f9156a5283fe', 'Encounter/11381dc6-0e06-da55-0735-d1e7bbf8bb35', 'DocumentReference/c84e67e9-4ea8-700b-9f2b-c0179e803d4f') +('c84e67e9-4ea8-700b-9f2b-c0179e803d4f', 'current', '51847-2', 'http://loinc.org', 'Evaluation + Plan note', None, None, datetime.date(2018, 7, 15), datetime.date(2018, 7, 15), datetime.date(2018, 7, 9), datetime.date(2018, 7, 1), datetime.date(2018, 1, 1), 'urn:ihe:iti:xds:2017:mimeTypeSufficient', 'Patient/dffa62dc-8ec2-1cd6-ee75-f9156a5283fe', 'Encounter/11381dc6-0e06-da55-0735-d1e7bbf8bb35', 'DocumentReference/c84e67e9-4ea8-700b-9f2b-c0179e803d4f') diff --git a/tests/test_data/core/core__observation_vital_signs.txt b/tests/test_data/core/core__observation_vital_signs.txt index 03303763..2a0966e1 100644 --- a/tests/test_data/core/core__observation_vital_signs.txt +++ b/tests/test_data/core/core__observation_vital_signs.txt @@ -1,2 +1,2 @@ -('000ee3e3-845d-922b-ddad-1e4f150eb845', '39156-5', 'http://loinc.org', 'vital-signs', 'http://terminology.hl7.org/CodeSystem/observation-category', None, None, None, 'final', None, None, None, datetime.date(2018, 7, 31), datetime.date(2018, 7, 30), datetime.date(2018, 7, 1), datetime.date(2018, 1, 1), 'Patient/6385ddd7-2639-6505-3789-0521b8f66c8b', 'Encounter/fd0754a4-e96d-cba7-b3c0-77697a09c86e', 'Observation/000ee3e3-845d-922b-ddad-1e4f150eb845') -('00104f5f-cd8f-c1b5-7585-f3421d98ae65', '72514-3', 'http://loinc.org', 'vital-signs', 'http://terminology.hl7.org/CodeSystem/observation-category', None, None, None, 'final', None, None, None, datetime.date(2018, 9, 20), datetime.date(2018, 9, 17), datetime.date(2018, 9, 1), datetime.date(2018, 1, 1), 'Patient/6385ddd7-2639-6505-3789-0521b8f66c8b', 'Encounter/fd0754a4-e96d-cba7-b3c0-77697a09c86e', 'Observation/00104f5f-cd8f-c1b5-7585-f3421d98ae65') +('000ee3e3-845d-922b-ddad-1e4f150eb845', '39156-5', 'http://loinc.org', 'vital-signs', 'http://terminology.hl7.org/CodeSystem/observation-category', None, None, None, 29.33, None, 'kg/m2', 'http://unitsofmeasure.org', 'kg/m2', 'final', None, None, None, datetime.date(2018, 7, 31), datetime.date(2018, 7, 30), datetime.date(2018, 7, 1), datetime.date(2018, 1, 1), 'Patient/6385ddd7-2639-6505-3789-0521b8f66c8b', 'Encounter/fd0754a4-e96d-cba7-b3c0-77697a09c86e', 'Observation/000ee3e3-845d-922b-ddad-1e4f150eb845') +('00104f5f-cd8f-c1b5-7585-f3421d98ae65', '72514-3', 'http://loinc.org', 'vital-signs', 'http://terminology.hl7.org/CodeSystem/observation-category', None, None, None, 2.0, None, '{score}', 'http://unitsofmeasure.org', '{score}', 'final', None, None, None, datetime.date(2018, 9, 20), datetime.date(2018, 9, 17), datetime.date(2018, 9, 1), datetime.date(2018, 1, 1), 'Patient/6385ddd7-2639-6505-3789-0521b8f66c8b', 'Encounter/fd0754a4-e96d-cba7-b3c0-77697a09c86e', 'Observation/00104f5f-cd8f-c1b5-7585-f3421d98ae65') diff --git a/tests/test_data/duckdb_data/observation/vitals.ndjson b/tests/test_data/duckdb_data/observation/vitals.ndjson index 0cef886e..607ff2c6 100644 --- a/tests/test_data/duckdb_data/observation/vitals.ndjson +++ b/tests/test_data/duckdb_data/observation/vitals.ndjson @@ -1,2 +1,2 @@ {"resourceType":"Observation","id":"000ee3e3-845d-922b-ddad-1e4f150eb845","meta":{"profile":["http://hl7.org/fhir/us/core/StructureDefinition/us-core-bmi"]},"status":"final","category":[{"coding":[{"system":"http://terminology.hl7.org/CodeSystem/observation-category","code":"vital-signs","display":"Vital signs"}]}],"code":{"coding":[{"system":"http://loinc.org","code":"39156-5","display":"Body mass index (BMI) [Ratio]"}],"text":"Body mass index (BMI) [Ratio]"},"subject":{"reference":"Patient/6385ddd7-2639-6505-3789-0521b8f66c8b"},"encounter":{"reference":"Encounter/fd0754a4-e96d-cba7-b3c0-77697a09c86e"},"effectiveDateTime":"2018-07-31T11:46:59-04:00","issued":"2018-07-31T11:46:59.829-04:00","valueQuantity":{"value":29.33,"unit":"kg/m2","system":"http://unitsofmeasure.org","code":"kg/m2"}} -{"resourceType":"Observation","id":"00104f5f-cd8f-c1b5-7585-f3421d98ae65","status":"final","category":[{"coding":[{"system":"http://terminology.hl7.org/CodeSystem/observation-category","code":"vital-signs","display":"Vital signs"}]}],"code":{"coding":[{"system":"http://loinc.org","code":"72514-3","display":"Pain severity - 0-10 verbal numeric rating [Score] - Reported"}],"text":"Pain severity - 0-10 verbal numeric rating [Score] - Reported"},"subject":{"reference":"Patient/6385ddd7-2639-6505-3789-0521b8f66c8b"},"encounter":{"reference":"Encounter/fd0754a4-e96d-cba7-b3c0-77697a09c86e"},"effectiveDateTime":"2018-09-20T09:37:16-04:00","issued":"2018-09-20T09:37:16.824-04:00","valueQuantity":{"value":2,"unit":"{score}","system":"http://unitsofmeasure.org","code":"{score}"}} +{"resourceType":"Observation","id":"00104f5f-cd8f-c1b5-7585-f3421d98ae65","status":"final","category":[{"coding":[{"system":"http://terminology.hl7.org/CodeSystem/observation-category","code":"vital-signs","display":"Vital signs"}]}],"code":{"coding":[{"system":"http://loinc.org","code":"72514-3","display":"Pain severity - 0-10 verbal numeric rating [Score] - Reported"}],"text":"Pain severity - 0-10 verbal numeric rating [Score] - Reported"},"subject":{"reference":"Patient/6385ddd7-2639-6505-3789-0521b8f66c8b"},"encounter":{"reference":"Encounter/fd0754a4-e96d-cba7-b3c0-77697a09c86e"},"effectiveDateTime":"2018-09-20T09:37:16-04:00","issued":"2018-09-20T09:37:16.824-04:00","valueQuantity":{"value":2,"unit":"{score}","system":"http://unitsofmeasure.org","code":"{score}"}, "component": [{"code": {"coding": [{"code": "{score}"}]}, "dataAbsentReason": {"text": "missing"}, "interpretation": [{"text": "all good"}]}]} diff --git a/tests/test_duckdb.py b/tests/test_duckdb.py index ac67142e..740d5a22 100644 --- a/tests/test_duckdb.py +++ b/tests/test_duckdb.py @@ -83,7 +83,12 @@ def test_duckdb_table_schema(): json.dump( { "id": "test", - "component": [{"dataAbsentReason": {"text": "Dunno"}}], + "component": [ + { + "dataAbsentReason": {"text": "Dunno"}, + "valuePeriod": {"id": "X"}, + } + ], "valueBoolean": False, }, ndjson, @@ -94,7 +99,11 @@ def test_duckdb_table_schema(): # Look for a mix of camel-cased and lower-cased fields. Both should work. target_schema = { "bodySite": [], - "CoMpOnEnT": ["dataabsentreason", "valueQuantity"], + "CoMpOnEnT": { + "dataabsentreason": [], + "valuePeriod": ["id"], + "valueQuantity": [], + }, "not_a_real_field": [], "valueboolean": [], } @@ -118,6 +127,7 @@ def test_duckdb_table_schema(): "bodySite": True, # real toplevel fields are guaranteed to be in schema "CoMpOnEnT": { "dataabsentreason": True, + "valuePeriod": {"id": True}, "valueQuantity": False, }, "not_a_real_field": False, diff --git a/tests/test_template_sql_utils.py b/tests/test_template_sql_utils.py index 4f8be574..8083f20b 100644 --- a/tests/test_template_sql_utils.py +++ b/tests/test_template_sql_utils.py @@ -32,6 +32,23 @@ ("encounter", [("period", dict)], None, False, does_not_raise()), # non coding with specific expected fields ("encounter", [("period", dict)], ["start", "end"], True, does_not_raise()), + # deeply nested field + ( + "encounter", + [ + ("hospitalization", dict), + ("dischargeDisposition", dict), + ("coding", list), + ], + { + "dischargeDisposition": { + "coding": ["code", "system"], + "text": {}, + }, + }, + True, + does_not_raise(), + ), ], ) def test_is_field_populated(mock_db, table, hierarchy, expected, returns, raises): @@ -42,5 +59,6 @@ def test_is_field_populated(mock_db, table, hierarchy, expected, returns, raises hierarchy=hierarchy, expected=expected, cursor=mock_db.cursor(), + parser=mock_db.parser(), ) assert res == returns diff --git a/tests/test_templates.py b/tests/test_templates.py index e04f4c2e..2b61e240 100644 --- a/tests/test_templates.py +++ b/tests/test_templates.py @@ -23,21 +23,32 @@ def test_codeable_concept_denormalize_all_creation(): expected = """CREATE TABLE target__concepts AS ( WITH + flattened_rows AS ( + SELECT DISTINCT + t.id AS id, + ROW_NUMBER() OVER (PARTITION BY id) AS row, + r."code_col" + FROM + source AS t, + UNNEST(t."code_col") AS r ("code_col") + ), + system_code_col_0 AS ( SELECT DISTINCT s.id AS id, + s.row, u.codeable_concept.code, u.codeable_concept.display, u.codeable_concept.system AS code_system FROM - source AS s, - UNNEST(s.code_col) AS cc (cc_row), - UNNEST(cc.cc_row.coding) AS u (codeable_concept) + flattened_rows AS s, + UNNEST(s.code_col.coding) AS u (codeable_concept) ), --noqa: LT07 union_table AS ( SELECT id, + row, code_system, code, display @@ -46,6 +57,7 @@ def test_codeable_concept_denormalize_all_creation(): ) SELECT id, + row, code, code_system, display @@ -69,6 +81,7 @@ def test_codeable_concept_denormalize_filter_creation(): system_code_col_0 AS ( SELECT DISTINCT s.id AS id, + 0 AS row, '0' AS priority, u.codeable_concept.code, u.codeable_concept.display, @@ -83,6 +96,7 @@ def test_codeable_concept_denormalize_filter_creation(): system_code_col_1 AS ( SELECT DISTINCT s.id AS id, + 0 AS row, '1' AS priority, u.codeable_concept.code, u.codeable_concept.display, @@ -97,6 +111,7 @@ def test_codeable_concept_denormalize_filter_creation(): union_table AS ( SELECT id, + row, priority, code_system, code, @@ -105,6 +120,7 @@ def test_codeable_concept_denormalize_filter_creation(): UNION SELECT id, + row, priority, code_system, code, @@ -116,6 +132,7 @@ def test_codeable_concept_denormalize_filter_creation(): partitioned_table AS ( SELECT id, + row, code, code_system, display, @@ -126,7 +143,7 @@ def test_codeable_concept_denormalize_filter_creation(): ORDER BY priority ASC ) AS available_priority FROM union_table - GROUP BY id, priority, code_system, code, display + GROUP BY id, row, priority, code_system, code, display ORDER BY priority ASC ) @@ -217,6 +234,7 @@ def test_create_view_query_creation(): (cast(NULL AS varchar),cast(NULL AS varchar)) ) AS t ("a","b") + WHERE 1 = 0 -- ensure empty table );""", "test_schema", "test_table", @@ -231,6 +249,7 @@ def test_create_view_query_creation(): (cast(NULL AS integer),cast(NULL AS varchar)) ) AS t ("a","b") + WHERE 1 = 0 -- ensure empty table );""", "test_schema", "test_table", @@ -283,7 +302,7 @@ def test_extension_denormalize_creation(): ext_child.ext.valuecoding.display AS prefix_display FROM source_table AS s, - UNNEST(extension) AS ext_parent (ext), + UNNEST(s.extension) AS ext_parent (ext), UNNEST(ext_parent.ext.extension) AS ext_child (ext) WHERE ext_parent.ext.url = 'fhir_extension' @@ -300,7 +319,7 @@ def test_extension_denormalize_creation(): ext_child.ext.valuecoding.display AS prefix_display FROM source_table AS s, - UNNEST(extension) AS ext_parent (ext), + UNNEST(s.extension) AS ext_parent (ext), UNNEST(ext_parent.ext.extension) AS ext_child (ext) WHERE ext_parent.ext.url = 'fhir_extension' diff --git a/tests/testbed_utils.py b/tests/testbed_utils.py index 94453da6..f8c6ae80 100644 --- a/tests/testbed_utils.py +++ b/tests/testbed_utils.py @@ -45,6 +45,17 @@ def add(self, table: str, obj: dict) -> None: # # All other args can be specified as a kwarg, like add() itself does. + def add_condition(self, row_id: str, recorded: str = "2020", **kwargs) -> None: + """Adds a Condition with all the SQL-required fields filled out""" + self.add( + "condition", + { + "id": row_id, + "recordedDate": recorded, + **kwargs, + }, + ) + def add_document_reference( self, row_id: str, start: str = "2020", **kwargs ) -> None: @@ -131,6 +142,17 @@ def add_etl_completion_encounters( }, ) + def add_observation(self, row_id: str, effective: str = "2020", **kwargs) -> None: + """Adds a Observation with all the SQL-required fields filled out""" + self.add( + "observation", + { + "id": row_id, + "effectiveDateTime": effective, + **kwargs, + }, + ) + def add_patient( self, row_id: str, birth_date: str = "2000", gender: str = "unknown", **kwargs ) -> None: