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

Make GoogleCloudServiceAccountDictProfileMapping dataset profile argument optional #839

7 changes: 5 additions & 2 deletions cosmos/profiles/bigquery/service_account_keyfile_dict.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ class GoogleCloudServiceAccountDictProfileMapping(BaseProfileMapping):

required_fields = [
"project",
"dataset",
"keyfile_json",
]

Expand All @@ -45,11 +44,15 @@ def profile(self) -> dict[str, Any | None]:
Even though the Airflow connection contains hard-coded Service account credentials,
we generate a temporary file and the DBT profile uses it.
"""
return {
profile = {
**self.mapped_params,
"threads": 1,
**self.profile_args,
}
if "dataset" in self.profile_args:
profile["dataset"] = self.profile_args["dataset"]

return profile
Comment on lines +52 to +55
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this is needed since if dataset is already in profile_args it will be merged above in:

       {
            **self.mapped_params,
            "threads": 1,
            **self.profile_args,
        }


@property
def mock_profile(self) -> dict[str, Any | None]:
Expand Down
32 changes: 29 additions & 3 deletions tests/profiles/bigquery/test_bq_service_account_keyfile_dict.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,8 @@ def test_connection_claiming_succeeds(mock_bigquery_conn_with_dict: Connection):


def test_connection_claiming_fails(mock_bigquery_conn_with_dict: Connection):
# Remove the `dataset` key, which is mandatory
mock_bigquery_conn_with_dict.extra = json.dumps({"project": "my_project", "keyfile_dict": sample_keyfile_dict})
# Remove the `project` key, which is mandatory
mock_bigquery_conn_with_dict.extra = json.dumps({"keyfile_dict": sample_keyfile_dict})
profile_mapping = GoogleCloudServiceAccountDictProfileMapping(mock_bigquery_conn_with_dict, {})
assert not profile_mapping.can_claim_connection()

Expand All @@ -87,6 +87,33 @@ def test_profile(mock_bigquery_conn_with_dict: Connection):
assert profile_mapping.profile == expected


def test_profile_without_dataset(mock_bigquery_conn_with_dict: Connection):
mock_bigquery_conn_with_dict.extra = json.dumps(
{
"project": "my_project",
"keyfile_dict": json.dumps(sample_keyfile_dict),
}
)

profile_mapping = GoogleCloudServiceAccountDictProfileMapping(mock_bigquery_conn_with_dict, {})

# Expected profile does not include 'dataset'
expected = {
"type": "bigquery",
"method": "service-account-json",
"project": "my_project",
"dataset": None,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you know if having None in the profile is OK when this is formatted to yaml in BaseProfile.get_profile_contents this would result in profile like:

dataset: null
keyfile_json:
  private_key: '{{ env_var(''COSMOS_CONN_GOOGLE_CLOUD_PLATFORM_PRIVATE_KEY'') }}'
  private_key_id: '{{ env_var(''COSMOS_CONN_GOOGLE_CLOUD_PLATFORM_PRIVATE_KEY_ID'')
    }}'
  type: service_account
method: service-account-json
project: my_project
threads: 1
type: bigquery

Would the dataset: null line above cause any issue?

"threads": 1,
"keyfile_json": {
"type": "service_account",
"private_key_id": "{{ env_var('COSMOS_CONN_GOOGLE_CLOUD_PLATFORM_PRIVATE_KEY_ID') }}",
"private_key": "{{ env_var('COSMOS_CONN_GOOGLE_CLOUD_PLATFORM_PRIVATE_KEY') }}",
},
}

assert profile_mapping.profile == expected


def test_mock_profile(mock_bigquery_conn_with_dict: Connection):
"""
Tests profile mock for keyfile_json is None. Giving keyfile_json a value will crash dbt ls.
Expand All @@ -96,7 +123,6 @@ def test_mock_profile(mock_bigquery_conn_with_dict: Connection):
"type": "bigquery",
"method": "service-account-json",
"project": "mock_value",
"dataset": "mock_value",
"threads": 1,
"keyfile_json": None,
}
Expand Down
Loading