Ejemplo n.º 1
0
    def __set_chart_dimension_classification(self, dimension, classification):
        chart = Chart.get_by_id(dimension.chart_id) or Chart()

        chart.classification_id = classification.classification_id
        chart.includes_parents = classification.includes_parents
        chart.includes_all = classification.includes_all
        chart.includes_unknown = classification.includes_unknown

        db.session.add(chart)
        db.session.flush()

        dimension.chart_id = chart.id

        db.session.add(dimension)
        db.session.commit()
def test_adding_table_with_custom_data_and_existing_less_detailed_chart(two_classifications_2A_5A):

    # Given an existing dimension with a chart with classification '2A' but no table
    dimension = dimension_service.create_dimension(
        MeasureVersionFactory(), title="test-dimension", time_period="time_period", summary="summary"
    )

    chart = Chart()
    chart.classification_id = "2A"
    chart.includes_parents = True
    chart.includes_all = False
    chart.includes_unknown = False
    chart.chart_object = {"chart_is_just_a": "dictionary"}
    chart.settings_and_source_data = {"values": 1}

    db.session.add(chart)
    db.session.commit()

    dimension.dimension_chart = chart

    # When update_dimension is called with table data and a matching
    # classification with code '5A'
    dimension_service.update_dimension(
        dimension,
        {
            "use_custom": True,
            "table": {"title": "My table title"},
            "table_settings_and_source_data": {"tableOptions": {}},
            "classification_code": "5A",
            "has_parents": False,
            "has_all": True,
            "has_unknown": True,
        },
        update_classification=True,
    )

    # Then it should set the table and associated metadata

    # refresh the dimension from the database
    dimension = Dimension.query.get(dimension.guid)

    # The table and table_settings_and_source_data objects get passed straight to the database
    assert dimension.dimension_table.table_object == {"title": "My table title"}
    assert dimension.dimension_table.settings_and_source_data == {"tableOptions": {}}

    # An associated Table should be created with the metadata given
    assert dimension.dimension_table is not None
    assert dimension.dimension_table.classification_id == "5A"
    assert dimension.dimension_table.includes_parents is False
    assert dimension.dimension_table.includes_all is True
    assert dimension.dimension_table.includes_unknown is True

    # And the dimension itself should have the same metadata as the newly saved table
    assert dimension.dimension_classification is not None
    assert dimension.dimension_classification.classification_id == "5A"
    assert dimension.dimension_classification.includes_parents is False
    assert dimension.dimension_classification.includes_all is True
    assert dimension.dimension_classification.includes_unknown is True
    def __set_chart_dimension_classification(self, dimension, classification):
        chart = dimension.dimension_chart or Chart()

        chart.classification_id = classification.classification_id
        chart.includes_parents = classification.includes_parents
        chart.includes_all = classification.includes_all
        chart.includes_unknown = classification.includes_unknown

        db.session.add(chart)
        db.session.flush(
        )  # Flush to DB will generate PK if it's a newly-created instance

        dimension.dimension_chart = chart

        db.session.commit()
    def update_dimension(
            self,
            dimension,
            data,
            update_classification=False):  # noqa: C901 (complexity)
        dimension.title = data["title"] if "title" in data else dimension.title
        dimension.time_period = data[
            "time_period"] if "time_period" in data else dimension.time_period
        dimension.summary = data[
            "summary"] if "summary" in data else dimension.summary
        if "chart" in data:
            if dimension.dimension_chart is None:
                dimension.dimension_chart = Chart()
            dimension.dimension_chart.chart_object = data["chart"]
        if "table" in data:
            if dimension.dimension_table is None:
                dimension.dimension_table = Table()
            dimension.dimension_table.table_object = data["table"]

        if (dimension.dimension_chart
                and dimension.dimension_chart.chart_object
                and data.get("chart_settings_and_source_data") is not None):
            chart_options = data.get("chart_settings_and_source_data").get(
                "chartOptions")
            for key, val in chart_options.items():
                if val is None:
                    chart_options[key] = "[None]"
            data["chart_settings_and_source_data"][
                "chartOptions"] = chart_options
            dimension.dimension_chart.settings_and_source_data = data.get(
                "chart_settings_and_source_data")
            if data["use_custom"] is False:
                self.__set_chart_dimension_classification_through_builder(
                    dimension, data)
            else:
                self.__set_chart_custom_dimension_classification(
                    dimension, data)

        if (dimension.dimension_table
                and dimension.dimension_table.table_object
                and data.get("table_settings_and_source_data") is not None):
            table_options = data.get("table_settings_and_source_data").get(
                "tableOptions")
            for key, val in table_options.items():
                if val is None:
                    table_options[key] = "[None]"
            data["table_settings_and_source_data"][
                "tableOptions"] = table_options
            dimension.dimension_table.settings_and_source_data = data.get(
                "table_settings_and_source_data")
            if data["use_custom"] is False:
                self.__set_table_dimension_classification_through_builder(
                    dimension, data)
            else:
                self.__set_table_custom_dimension_classification(
                    dimension, data)

        dimension.set_updated_at()

        # This should be True if the update has come in from chart or table builder
        # but False if the dimension metadata form has been submitted with no update to chart or table
        if update_classification:
            dimension.update_dimension_classification_from_chart_or_table()

        db.session.commit()
Ejemplo n.º 5
0
def copy_chart_and_table_data(app):  # noqa: C901
    with app.app_context():
        try:
            count = 0
            chart_failures = 0
            table_failures = 0
            for dimension in Dimension.query.all():
                # If there is a chart object, copy it to the chart table
                if dimension.chart:
                    # Create a Chart() if necessary
                    if dimension.dimension_chart is None:
                        dimension.dimension_chart = Chart()

                    # Don't overwrite if it already exists
                    if dimension.dimension_chart.chart_object is None:
                        dimension.dimension_chart.chart_object = dimension.chart

                    if dimension.chart_2_source_data is not None:
                        # If there is already a version 2 chart settings, copy settings straight across
                        # But don't overwrite if it already exists
                        if dimension.dimension_chart.settings_and_source_data is None:
                            dimension.dimension_chart.settings_and_source_data = dimension.chart_2_source_data
                    else:
                        # Assume there are version 1 settings if no version 2; convert it and copy it across
                        try:
                            version_2_settings = ChartObjectDataBuilder.upgrade_v1_to_v2(
                                dimension.chart, dimension.chart_source_data
                            )
                            # Don't overwrite if it already exists
                            if dimension.dimension_chart.settings_and_source_data is None:
                                dimension.dimension_chart.settings_and_source_data = version_2_settings
                        except Exception as e:
                            chart_failures += 1
                            print(f"Error copying chart for {dimension.title} ({dimension.guid})")
                            print(f"  CHART EXCEPTION: {type(e)}: {e}")

                # If there is a table object, copy it to the table table
                if dimension.table:
                    # Create a Table() if necessary
                    if dimension.dimension_table is None:
                        dimension.dimension_table = Table()

                    # Don't overwrite if it already exists
                    if dimension.dimension_table.table_object is None:
                        dimension.dimension_table.table_object = dimension.table

                    if dimension.table_2_source_data is not None:
                        # If there is already a version 2 table settings, copy settings straight across
                        # But don't overwrite if it already exists
                        if dimension.dimension_table.settings_and_source_data is None:
                            dimension.dimension_table.settings_and_source_data = dimension.table_2_source_data
                    else:
                        # Assume there are version 1 settings if no version 2; convert it and copy it across
                        try:
                            version_2_settings = TableObjectDataBuilder.upgrade_v1_to_v2(
                                dimension.table, dimension.table_source_data, current_app.dictionary_lookup
                            )
                            # Don't overwrite if it already exists
                            if dimension.dimension_table.settings_and_source_data is None:
                                dimension.dimension_table.settings_and_source_data = version_2_settings
                        except Exception as e:
                            table_failures += 1
                            print(f"Error copying table for {dimension.title} ({dimension.guid})")
                            print(f"  TABLE EXCEPTION: {type(e)}: {e}")

                count += 1

            db.session.commit()
            print(f"Total: {count}, Chart failures: {chart_failures}, Table failures: {table_failures}")

        except Exception as e:
            print(e)
            db.session.rollback()
            raise e

        finally:
            db.session.close()