diff --git a/superset/db_engine_specs/bigquery.py b/superset/db_engine_specs/bigquery.py index 51fd710ab335..85fb9576acaf 100644 --- a/superset/db_engine_specs/bigquery.py +++ b/superset/db_engine_specs/bigquery.py @@ -386,7 +386,9 @@ def get_parameters_from_uri( # Building parameters from encrypted_extra and uri if encrypted_extra: - return {**encrypted_extra, "query": value.query} + # ``value.query`` needs to be explicitly converted into a dict (from an + # ``immutabledict``) so that it can be JSON serialized + return {**encrypted_extra, "query": dict(value.query)} raise ValidationError("Invalid service credentials") diff --git a/tests/unit_tests/db_engine_specs/test_bigquery.py b/tests/unit_tests/db_engine_specs/test_bigquery.py index 292ea94a7b52..db8ff147542b 100644 --- a/tests/unit_tests/db_engine_specs/test_bigquery.py +++ b/tests/unit_tests/db_engine_specs/test_bigquery.py @@ -16,6 +16,8 @@ # under the License. # pylint: disable=unused-argument, import-outside-toplevel, protected-access +import json + from pybigquery.sqlalchemy_bigquery import BigQueryDialect from pytest_mock import MockFixture from sqlalchemy import select @@ -144,3 +146,17 @@ def test_select_star(mocker: MockFixture) -> None: FROM `my_table` LIMIT :param_1""" ) + + +def test_get_parameters_from_uri() -> None: + """ + Test that the result from ``get_parameters_from_uri`` is JSON serializable. + """ + from superset.db_engine_specs.bigquery import BigQueryEngineSpec + + parameters = BigQueryEngineSpec.get_parameters_from_uri( + "bigquery://dbt-tutorial-347100/", + {"access_token": "TOP_SECRET"}, + ) + assert parameters == {"access_token": "TOP_SECRET", "query": {}} + assert json.loads(json.dumps(parameters)) == parameters