Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extract rules #1951

Open
wants to merge 4 commits into
base: v0.21.0
Choose a base branch
from
Open

Extract rules #1951

wants to merge 4 commits into from

Conversation

fredkingham
Copy link
Contributor

@fredkingham fredkingham commented Jan 24, 2021

This branch is a proposal it works and returns the same as the old function (with a change of order) but is mostly just for debate.

1. I just want to add a bunch of csvs... you can declare extract_rule.ExtractRule.

This is initialised with the list of episodes and the user.

Add a write_to_file (which takes the directory to write to as an argument and returns a list of the file names that you wrote, or None)

Add a get_data_dictionary method which returns

{
            {{ display_name }}: [{
                display_name: {{ field display name }},
                description: {{ field description }},
                type_display_name: {{ field type }},
            }]
}

2. I want to change the fields that are in every csv.

You can declare a function in settings called EXTRACT_BASE_FIELDS that takes a user and returns the fields that the user should see in all files.

Cookbook

1. Rather than have an extract rule for allergies I want 1 row per patient with the allergy.drugs as a comma seperated list.

Add _exclude_from_extract=True to allergies

class Allergy(extract_rule.ExtractRule):
    def write_to_file(self, directory):
        allergies = Allergy.objects.filter(episode_id__in=[i.id for i in self.episode_list])
        episode_id_to_drug = defaultdict(list)
        base_field_dict = self.get_episode_id_to_base_fields_dict()
        for allergy in allergies:
            episode_id_to_drug[allergy.episode_id].append(allergy.drug)
        rows = []
        for episode_id, drugs in episode_id_to_drug.items():
            row = {"drugs": ",".join(drugs)}
            row.update(base_field_dict[episode_id])
            rows.append(row)

        file_name = os.path.join(directory, "allergies.csv")
        with open(file_name, "w"): as f:
            # sort your rows and write them to file.

    def get_data_dictionary(self):
        return {
            models.Allergy.get_display_name(): [{
                "display_name": "Drugs",
                "description": "A list of the patients drug allergies",
                "type_display_name": "A comma seperated list"
            }]
        }

2. I want to add the field 'within the last week' to PatientConsultation

Add _exclude_from_extract=True to PatientConsulation. This is not strictly necessary as the rule will run after the subrecord extract is done, but it stops additional computation.

Then add the extract rule.

class PatientConsultation(extract_rule.ModelRule):
    model = Episode
    path_to_episode_id = "patient__episode__id"
    additional_fields = ["within_the_last_week"]

    def get_within_the_last_week_description(self):
        return {
            "display_name": "Within the last week",
            "description": "returns True if the consultation was within the last week.",
            "type_display_name": "Either True, False or None"
        }

    def extract_within_the_last_week(self, instance):
        if instance.when:
            seven_days_ago = datetime.today() - timedelta(days=7)
            return seven_days_ago > instance.when:

3. I want to remove the field drug from allergies

In the models.py change

class Allergy(opal_models.Allergy):
    @classmethod
    def _get_fieldnames_to_extract(cls):
        field_names = super()._get_fieldnames_to_extract()
        field_names.remove("drug")
        return field_names

4. I want to add first_name, surname for all users

settings.py

EXTRACT_BASE_FIELDS "my_app.extract_rule.get_base_fields'

extract_rule.py

    def get_base_fields(user):
        return {
            "patient__demographics__first_name",
            "patient__demographics__surname",
        }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant