def update_results_data_schema()

in experimenter/experimenter/experiments/migrations/0266_nimbusexperiment_results_pairwise_data.py [0:0]


def update_results_data_schema(apps, schema_editor):
    NimbusExperiment = apps.get_model("experiments", "NimbusExperiment")

    for experiment in NimbusExperiment.objects.all():
        branches = [b.slug for b in experiment.branches.all()]
        reference_branch = experiment.reference_branch
        data = experiment.results_data
        if data is not None and "v3" not in data and "v2" in data:
            data["v3"] = data["v2"]

            # data for v3 looks like this (with changes vs v2 noted):
            # [window]: {
            #     [analysis_basis]: {
            #         [segment]: {
            #             [branch]: {
            #                 "branch_data": {
            #                     [metrics_group]: {
            #                         [metric_name]: {
            #                             "absolute": {
            #                                 "all": [...],
            #                                 "first": {...}
            #                             },
            #                             "difference": {
            #                                 // "all" and "first" moved from here into [comparison_branch]
            #                                 [comparison_branch]: { // this level is new
            #                                     "all": [...],
            #                                     "first": {...},
            #                                 },
            #                             },
            #                             "relative_uplift": {
            #                                 // "all" and "first" moved from here into [comparison_branch]
            #                                 [comparison_branch]: { // this level is new
            #                                     "all": [...],
            #                                     "first": {...},
            #                                 },
            #                             },
            #                             "significance": {
            #                                 // optional daily/weekly/overall moved from here into [comparison_branch]
            #                                 [comparison_branch]: { // this level is new
            #                                     "weekly": {},
            #                                     "overall: {}
            #                                 }
            #                             },
            #                             "percent": 0.0

            comparison_default = {"first": {}, "all": []}
            significance_default = {"weekly": {}, "overall": []}

            for key, value in data["v3"].items():
                if value is None or key not in ["weekly", "overall"]:
                    continue
                for basis, basis_data in value.items():
                    for segment, segment_data in basis_data.items():
                        # look up reference_branch from results data if we don't already know it
                        if reference_branch is None:
                            for branch_name, v in segment_data.items():
                                if v["is_control"] == True:
                                    reference_branch = branch_name
                                    break
                        for cur_branch, branch_data_obj in segment_data.items():
                            branch_data = branch_data_obj["branch_data"]
                            for (
                                metrics_group,
                                metrics,
                            ) in branch_data.items():
                                for metric, metric_data in metrics.items():
                                    for (
                                        comparison,
                                        comparison_data,
                                    ) in metric_data.items():
                                        if not isinstance(comparison_data, dict):
                                            continue
                                        metric_data_keys = [
                                            k for k in comparison_data.keys()
                                        ]
                                        if not set(branches).issubset(metric_data_keys):
                                            comparison_data_value = deepcopy(
                                                comparison_data
                                            )
                                            if comparison in [
                                                "difference",
                                                "relative_uplift",
                                            ]:
                                                data["v3"][key][basis][segment][
                                                    cur_branch
                                                ]["branch_data"][metrics_group][metric][
                                                    comparison
                                                ] = {}
                                                for branch in branches:
                                                    if (
                                                        branch == reference_branch
                                                        and cur_branch != reference_branch
                                                    ):
                                                        data["v3"][key][basis][segment][
                                                            cur_branch
                                                        ]["branch_data"][metrics_group][
                                                            metric
                                                        ][comparison][
                                                            reference_branch
                                                        ] = comparison_data_value
                                                    else:
                                                        data["v3"][key][basis][segment][
                                                            cur_branch
                                                        ]["branch_data"][metrics_group][
                                                            metric
                                                        ][comparison][
                                                            branch
                                                        ] = comparison_default

                                            elif comparison == "significance":
                                                data["v3"][key][basis][segment][
                                                    cur_branch
                                                ]["branch_data"][metrics_group][metric][
                                                    comparison
                                                ] = {}
                                                for branch in branches:
                                                    if (
                                                        branch == reference_branch
                                                        and cur_branch != reference_branch
                                                    ):
                                                        data["v3"][key][basis][segment][
                                                            cur_branch
                                                        ]["branch_data"][metrics_group][
                                                            metric
                                                        ][comparison][
                                                            reference_branch
                                                        ] = comparison_data_value
                                                    else:
                                                        data["v3"][key][basis][segment][
                                                            cur_branch
                                                        ]["branch_data"][metrics_group][
                                                            metric
                                                        ][comparison][
                                                            branch
                                                        ] = significance_default
            experiment.results_data = data
            experiment.save()