apache / superset

Apache Superset is a Data Visualization and Data Exploration Platform
https://superset.apache.org/
Apache License 2.0
62.8k stars 13.87k forks source link

fix(dashboard-export): Fixes datasetId is not replaced with datasetUuid in Dashboard export in 4.1.x #30425

Closed fmannhardt closed 1 month ago

fmannhardt commented 1 month ago

SUMMARY

Fixes #30424 by duplicating the code that rewrites the native_filter_configuration to use datasetUuid instead of datasetId into the _file_content method of ExportDashboardsCommand.

BEFORE/AFTER SCREENSHOTS OR ANIMATED GIF

Before the targets attribute of native_filter_configuration items includes datasetId:

    targets:
    - datasetId: 17
      column:
        name: column_name

After it just has datasetUuid:

    targets:
    - column:
        name: column_name
      datasetUuid: 7ac464dc-315a-4c9e-b9ec-048d7bbcf382```

TESTING INSTRUCTIONS

(1) Create a dashboard with any chart (2) Add a single value filter for any column (3) Export the dashboard (4) Verify that datasetUuid is used to refer to the dataset and not datasetId

ADDITIONAL INFORMATION

codecov[bot] commented 1 month ago

Codecov Report

Attention: Patch coverage is 21.42857% with 11 lines in your changes missing coverage. Please review.

Project coverage is 83.92%. Comparing base (76d897e) to head (f8171fd). Report is 966 commits behind head on master.

Files with missing lines Patch % Lines
superset/commands/dashboard/export.py 21.42% 11 Missing :warning:
Additional details and impacted files ```diff @@ Coverage Diff @@ ## master #30425 +/- ## =========================================== + Coverage 60.48% 83.92% +23.43% =========================================== Files 1931 533 -1398 Lines 76236 38546 -37690 Branches 8568 0 -8568 =========================================== - Hits 46114 32348 -13766 + Misses 28017 6198 -21819 + Partials 2105 0 -2105 ``` | [Flag](https://app.codecov.io/gh/apache/superset/pull/30425/flags?src=pr&el=flags&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) | Coverage Δ | | |---|---|---| | [hive](https://app.codecov.io/gh/apache/superset/pull/30425/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) | `48.99% <0.00%> (-0.17%)` | :arrow_down: | | [javascript](https://app.codecov.io/gh/apache/superset/pull/30425/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) | `?` | | | [mysql](https://app.codecov.io/gh/apache/superset/pull/30425/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) | `76.79% <21.42%> (?)` | | | [postgres](https://app.codecov.io/gh/apache/superset/pull/30425/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) | `76.89% <21.42%> (?)` | | | [presto](https://app.codecov.io/gh/apache/superset/pull/30425/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) | `53.48% <0.00%> (-0.32%)` | :arrow_down: | | [python](https://app.codecov.io/gh/apache/superset/pull/30425/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) | `83.92% <21.42%> (+20.43%)` | :arrow_up: | | [sqlite](https://app.codecov.io/gh/apache/superset/pull/30425/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) | `76.33% <21.42%> (?)` | | | [unit](https://app.codecov.io/gh/apache/superset/pull/30425/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) | `60.71% <0.00%> (+3.08%)` | :arrow_up: | Flags with carried forward coverage won't be shown. [Click here](https://docs.codecov.io/docs/carryforward-flags?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache#carryforward-flags-in-the-pull-request-comment) to find out more.

:umbrella: View full report in Codecov by Sentry.
:loudspeaker: Have feedback on the report? Share it here.

mistercrunch commented 1 month ago

Could you write a unit test that would fail before and succeed after? That will help review the logic by stating the assumptions in a unit test.

fmannhardt commented 1 month ago

Happy to do so. Since I have no clue of the testing approach of Superset, could you help me find the correct spot to test? Would the correct file be: https://github.com/apache/superset/blob/cc9fd88c0d2a2406f202da7dcea2f0d14f1d017e/tests/unit_tests/commands/export_test.py#L62 or rather an integration test (since this also concerns code that also exports other resources: https://github.com/apache/superset/blob/cc9fd88c0d2a2406f202da7dcea2f0d14f1d017e/tests/integration_tests/dashboards/commands_tests.py#L67

fmannhardt commented 1 month ago

After some more searching, the example data used in the tests comes from here: https://github.com/apache/superset/blob/master/superset/examples/world_bank.py and are manually created via code right? Or is there somewhere examples that exists as YAML files using the import/export feature?

Searching for native in the examples folder does not find anything: https://github.com/search?q=repo%3Aapache%2Fsuperset+path%3A%2F%5Esuperset%5C%2Fexamples%5C%2F%2F+native&type=code

So, I would need to write code to create a dashboard with native filters from scratch? Or would there be a simpler way to write such test? I would need some guidance.

sadpandajoe commented 1 month ago

@fmannhardt I created a PR to the covid vaccine example dashboard. I'm guessing you can probably add a test here: https://github.com/apache/superset/blob/master/tests/integration_tests/dashboards/commands_tests.py#L67 or update one of the tests to make sure when exporting native filter meta data is there.

Vitor-Avila commented 1 month ago

Hey @fmannhardt,

Thanks for working on this fix! 🙏

Looking at the code changes, I noticed you have re-introduced that code block to file_content, but it also remains present in the _export method. Is it required to have this block in both? For instance I see the dataset_id = target.pop("datasetId", None) in both blocks.

If we need them in both places, should we consider to move this logic to a helper/etc method to make it DRYer?

fmannhardt commented 1 month ago

@Vitor-Avila I think it is required in both places to also invoke the export of the related datasets via yield from ExportDatasetsCommand([dataset_id]).run(). I agree that a refactoring would make sense. However, then there are also other parts that are duplicated such as:

        payload = model.export_to_dict(
            recursive=False,
            include_parent_ref=False,
            include_defaults=True,
            export_uuids=True,

It seems to me that a completely different approach to separate the export to YAML/JSON and walking the dependency graph of the to be exported dashboard would be better. Maybe, first collecting all the dependencies and then going through the list of dependencies and exporting them. However, that would exceed the capacity that I have for contributing right now (and I am also not aware of any design decision that led to the current approach).

I will try to add the test in the next few days.

sadpandajoe commented 1 month ago

@fmannhardt @Vitor-Avila as this would be a regression for 4.1, let's I'd advise that we just add the tests and then if we need to refactor, refactor in a separate pr.

fmannhardt commented 1 month ago

It seems that I also need to write a fixture for the COVID dashboard, right? Bare with me, still exploring the setup of Superset testing and locally many other tests fail probably due to missing dependencies. I will try to look at this tomorrow.

villebro commented 1 month ago

@fmannhardt thanks for working on this super critical regression. I will be reviewing this today and do my best to help unblock you.

villebro commented 1 month ago

Note: this is a fix for a regression that was introduced by #26765

villebro commented 1 month ago

It seems that I also need to write a fixture for the COVID dashboard, right? Bare with me, still exploring the setup of Superset testing and locally many other tests fail probably due to missing dependencies. I will try to look at this tomorrow.

@fmannhardt you are correct - if there isn't a fixture that creates this dashboard + related assets, then you will need to add one. Let me know if you need help with this.

fmannhardt commented 1 month ago

Happy to help and thanks for the work on Superset. I may have time to look at this tomorrow (UTC+1). So, the existing fixtures hard code the dashboard and do not load from the examples? Just so I understand how to write it. It would be a copy of world_bank_dashboard.py but then the COVID dashboard code in there?

In case, it is easy for you to add the fixture I am also happy to update the test I wrote to work against it.

villebro commented 1 month ago

Happy to help and thanks for the work on Superset. I may have time to look at this tomorrow (UTC+1). So, the existing fixtures hard code the dashboard and do not load from the examples? Just so I understand how to write it. It would be a copy of world_bank_dashboard.py but then the COVID dashboard code in there?

In case, it is easy for you to add the fixture I am also happy to update the test I wrote to work against it.

@fmannhardt let me take a look how it's been implemented (my memory is rusty on these particular fixtures)..

villebro commented 1 month ago

@fmannhardt I took a quick look at that particular fixture, and it seems to be mostly reusing existing logic. However, the data seems to be randomly generated for some reason. I'm not sure why, but maybe it's to avoid unnecessary web traffic. Please keep an open mind while working on the fixture, and if you feel some aspect could be improved compared to the World Bank fixture, then please by all means feel free to implement accordingly. I'm in UTC-0700, so I can help/review tomorrow morning my time if needed, likely after you've had a chance to take a stab at it first.

fmannhardt commented 1 month ago

@villebro I took another look but this would take me much more time to understand. I don't even need to data for the test. Only the have the COVID dashboard and its dataset loaded and available to be queries by UUID f4065089-110a-41fa-8dd7-9ce98a65e250. It is probably trivial but would take me several hours. So, it would take some more days. Please feel free to add this.

villebro commented 1 month ago

@fmannhardt I totally understand. Feel free to disable the added test - I'll open a PR that adds the necessary fixtures and re-enables the test.

fmannhardt commented 1 month ago

Test is disabled and current master branch is merged.

sadpandajoe commented 1 month ago

/testenv up

github-actions[bot] commented 1 month ago

@sadpandajoe Ephemeral environment spinning up at http://35.167.172.107:8080. Credentials are admin/admin. Please allow several minutes for bootstrapping and startup.

villebro commented 1 month ago

I'm merging now, will follow up with those tests.

github-actions[bot] commented 1 month ago

Ephemeral environment shutdown and build artifacts deleted.