Skip to content

Commit 1299d74

Browse files
committed
feat: add new fields regarding NULL values
jira: CQ-1959 risk: low
1 parent bc9fcd8 commit 1299d74

6 files changed

Lines changed: 38 additions & 15 deletions

File tree

packages/gooddata-sdk/src/gooddata_sdk/catalog/data_source/action_model/requests/ldm_request.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ class CatalogGenerateLdmRequest(Base):
5151
wdf_prefix: Optional[str] = None
5252
pdm: Optional[CatalogPdmLdmRequest] = None
5353
workspace_id: Optional[str] = None
54+
translation_prefix: Optional[str] = None
5455

5556
@staticmethod
5657
def client_class() -> type[GenerateLdmRequest]:

packages/gooddata-sdk/src/gooddata_sdk/catalog/data_source/declarative_model/physical_model/column.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ class CatalogDeclarativeColumn(Base):
1616
is_primary_key: Optional[bool] = None
1717
referenced_table_id: Optional[str] = None
1818
referenced_table_column: Optional[str] = None
19+
is_nullable: Optional[bool] = None
20+
null_value: Optional[str] = None
1921

2022
@staticmethod
2123
def client_class() -> type[DeclarativeColumn]:

packages/gooddata-sdk/src/gooddata_sdk/catalog/workspace/declarative_model/workspace/logical_model/dataset/dataset.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,8 @@ class CatalogDeclarativeAttribute(Base):
8282
tags: Optional[list[str]] = None
8383
is_hidden: Optional[bool] = None
8484
locale: Optional[str] = None
85+
is_nullable: Optional[bool] = None
86+
null_value: Optional[str] = None
8587

8688
@staticmethod
8789
def client_class() -> type[DeclarativeAttribute]:
@@ -97,6 +99,8 @@ class CatalogDeclarativeFact(Base):
9799
description: Optional[str] = None
98100
tags: Optional[list[str]] = None
99101
is_hidden: Optional[bool] = None
102+
is_nullable: Optional[bool] = None
103+
null_value: Optional[str] = None
100104

101105
@staticmethod
102106
def client_class() -> type[DeclarativeFact]:
@@ -121,6 +125,8 @@ class CatalogDeclarativeAggregatedFact(Base):
121125
source_column_data_type: Optional[str] = None
122126
description: Optional[str] = None
123127
tags: Optional[list[str]] = None
128+
is_nullable: Optional[bool] = None
129+
null_value: Optional[str] = None
124130

125131
@staticmethod
126132
def client_class() -> type[DeclarativeAggregatedFact]:
@@ -171,6 +177,8 @@ class CatalogDeclarativeLabel(Base):
171177
locale: Optional[str] = None
172178
translations: Optional[list[CatalogDeclarativeLabelTranslation]] = None
173179
geo_area_config: Optional[CatalogGeoAreaConfig] = None
180+
is_nullable: Optional[bool] = None
181+
null_value: Optional[str] = None
174182

175183
@staticmethod
176184
def client_class() -> type[DeclarativeLabel]:
@@ -203,6 +211,8 @@ class CatalogDeclarativeReference(Base):
203211
source_columns: Optional[list[str]] = None
204212
source_column_data_types: Optional[list[str]] = None
205213
sources: Optional[list[CatalogDeclarativeReferenceSource]] = None
214+
is_nullable: Optional[bool] = None
215+
null_value: Optional[str] = None
206216

207217
@staticmethod
208218
def client_class() -> type[DeclarativeReference]:

packages/gooddata-sdk/tests/catalog/expected/declarative_workspaces.json

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2597,13 +2597,6 @@
25972597
"id": "geo__state__location",
25982598
"sourceColumn": "geo__state__location",
25992599
"sourceColumnDataType": "STRING",
2600-
"locale": "en-US",
2601-
"translations": [
2602-
{
2603-
"locale": "cs-CZ",
2604-
"sourceColumn": "geo__state__location_cz"
2605-
}
2606-
],
26072600
"tags": [
26082601
"Customers"
26092602
],

packages/gooddata-sdk/tests/catalog/test_catalog_data_source.py

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
)
4545
from gooddata_sdk.catalog.data_source.entity_model.data_source import DatabaseAttributes
4646
from gooddata_sdk.catalog.entity import ClientSecretCredentialsFromFile
47+
from tests_support.compare_utils import deep_eq
4748
from tests_support.file_utils import load_json
4849
from tests_support.vcrpy_utils import get_vcr
4950

@@ -78,7 +79,11 @@ def test_generate_logical_model(test_config: dict):
7879
sdk = GoodDataSdk.create(host_=test_config["host"], token_=test_config["token"])
7980
declarative_model = sdk.catalog_workspace_content.get_declarative_ldm(test_config["workspace"])
8081
generate_ldm_request = CatalogGenerateLdmRequest(
81-
separator="__", wdf_prefix="wdf", workspace_id=test_config["workspace"], pdm=pdm_ldm_request
82+
separator="__",
83+
wdf_prefix="wdf",
84+
workspace_id=test_config["workspace"],
85+
pdm=pdm_ldm_request,
86+
translation_prefix="tr",
8287
)
8388
generated_declarative_model = sdk.catalog_data_source.generate_logical_model(
8489
test_config["data_source"], generate_ldm_request
@@ -93,7 +98,11 @@ def test_generate_logical_model(test_config: dict):
9398
"""
9499
# Filter out SQL-based datasets (those have sql property set, no data_source_table_id)
95100
table_based_datasets = [ds for ds in declarative_model.ldm.datasets if ds.sql is None]
96-
assert table_based_datasets == generated_declarative_model.ldm.datasets
101+
102+
for i, dataset in enumerate(table_based_datasets):
103+
print(f"Dataset: {dataset.id}")
104+
assert deep_eq(dataset, generated_declarative_model.ldm.datasets[i])
105+
97106
assert len(declarative_model.ldm.date_instances) == len(generated_declarative_model.ldm.date_instances)
98107

99108

@@ -102,7 +111,7 @@ def test_scan_pdm_and_generate_logical_model(test_config: dict):
102111
sdk = GoodDataSdk.create(host_=test_config["host"], token_=test_config["token"])
103112
declarative_model = sdk.catalog_workspace_content.get_declarative_ldm(test_config["workspace"])
104113
generate_ldm_request = CatalogGenerateLdmRequest(
105-
separator="__", wdf_prefix="wdf", workspace_id=test_config["workspace"]
114+
separator="__", wdf_prefix="wdf", workspace_id=test_config["workspace"], translation_prefix="tr"
106115
)
107116
generated_declarative_model, _ = sdk.catalog_data_source.scan_pdm_and_generate_logical_model(
108117
test_config["data_source"], generate_ldm_request
@@ -117,7 +126,10 @@ def test_scan_pdm_and_generate_logical_model(test_config: dict):
117126
"""
118127
# Filter out SQL-based datasets (those have sql property set, no data_source_table_id)
119128
table_based_datasets = [ds for ds in declarative_model.ldm.datasets if ds.sql is None]
120-
assert table_based_datasets == generated_declarative_model.ldm.datasets
129+
for i, dataset in enumerate(table_based_datasets):
130+
print(f"Dataset: {dataset.id}")
131+
assert deep_eq(dataset, generated_declarative_model.ldm.datasets[i], [r"\['is_nullable'\]"])
132+
121133
assert len(declarative_model.ldm.date_instances) == len(generated_declarative_model.ldm.date_instances)
122134

123135

@@ -182,7 +194,9 @@ def test_generate_logical_model_with_sql_datasets(test_config: dict):
182194
# and remove sort once fixed
183195
generated_declarative_model.ldm.datasets.sort(key=lambda dataset: dataset.id)
184196
expected_ldm.ldm.datasets.sort(key=lambda dataset: dataset.id)
185-
assert expected_ldm.ldm.datasets == generated_declarative_model.ldm.datasets
197+
for i, dataset in enumerate(expected_ldm.ldm.datasets):
198+
print(f"Dataset: {dataset.id}")
199+
assert deep_eq(dataset, generated_declarative_model.ldm.datasets[i])
186200
assert len(expected_ldm.ldm.date_instances) == len(generated_declarative_model.ldm.date_instances)
187201

188202

@@ -197,6 +211,7 @@ def test_scan_pdm_and_generate_logical_model_with_sql_datasets(test_config: dict
197211
pdm=CatalogPdmLdmRequest(
198212
sqls=build_pdm_sql_datasets(),
199213
),
214+
translation_prefix="tr",
200215
)
201216
generated_declarative_model, scan_result = sdk.catalog_data_source.scan_pdm_and_generate_logical_model(
202217
test_config["data_source"], ldm_request
@@ -208,7 +223,9 @@ def test_scan_pdm_and_generate_logical_model_with_sql_datasets(test_config: dict
208223
# and remove sort once fixed
209224
generated_declarative_model.ldm.datasets.sort(key=lambda dataset: dataset.id)
210225
expected_ldm.ldm.datasets.sort(key=lambda dataset: dataset.id)
211-
assert expected_ldm.ldm.datasets == generated_declarative_model.ldm.datasets
226+
for i, dataset in enumerate(expected_ldm.ldm.datasets):
227+
print(f"Dataset {dataset.id}")
228+
assert deep_eq(dataset, generated_declarative_model.ldm.datasets[i], [r"\['is_nullable'\]"])
212229
assert len(expected_ldm.ldm.date_instances) == len(generated_declarative_model.ldm.date_instances)
213230

214231

packages/tests-support/src/tests_support/compare_utils.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@
44
from deepdiff import DeepDiff
55

66

7-
def deep_eq(expected: any, actual: any) -> bool:
7+
def deep_eq(expected: any, actual: any, exclude_regex_paths: list[str] | None = None) -> bool:
88
if expected != actual:
9-
print(DeepDiff(expected, actual))
9+
print(DeepDiff(expected, actual, exclude_regex_paths=exclude_regex_paths))
1010
return False
1111

1212
return True

0 commit comments

Comments
 (0)