Skip to content

Commit 0d72f3c

Browse files
committed
test: add aggregated dataset to testing ldm
risk: nonprod
1 parent 1c8cffe commit 0d72f3c

File tree

10 files changed

+259
-11
lines changed

10 files changed

+259
-11
lines changed

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ class CatalogDeclarativeDataset(Base):
4242
attributes: Optional[list[CatalogDeclarativeAttribute]] = None
4343
facts: Optional[list[CatalogDeclarativeFact]] = None
4444
aggregated_facts: Optional[list[CatalogDeclarativeAggregatedFact]] = None
45+
precedence: Optional[int] = None
4546
data_source_table_id: Optional[CatalogDataSourceTableIdentifier] = None
4647
sql: Optional[CatalogDeclarativeDatasetSql] = None
4748
tags: Optional[list[str]] = None

gooddata-sdk/gooddata_sdk/catalog/workspace/entity_model/content_objects/dataset.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,14 @@ def generate_facts_from_api(self) -> list[CatalogFact]:
145145
default=attr.Factory(lambda self: self.generate_facts_from_api(), takes_self=True),
146146
)
147147

148+
# TODO: Doublecheck if we shouldn't do something like for facts
149+
aggregated_facts: Optional[list[CatalogAggregatedFact]] = attr.field(
150+
default=attr.Factory(lambda self: self.json_api_attributes.get("aggregatedFacts"), takes_self=True),
151+
)
152+
precedence: Optional[int] = attr.field(
153+
default=attr.Factory(lambda self: self.json_api_attributes.get("precedence"), takes_self=True)
154+
)
155+
148156
grain: Optional[list] = attr.field(
149157
default=attr.Factory(lambda self: self.json_api_attributes.get("grain"), takes_self=True)
150158
)

gooddata-sdk/gooddata_sdk/catalog/workspace/model_container.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
from gooddata_sdk.catalog.types import ValidObjects
88
from gooddata_sdk.catalog.workspace.entity_model.content_objects.dataset import (
9+
CatalogAggregatedFact,
910
CatalogAttribute,
1011
CatalogDataset,
1112
CatalogFact,
@@ -46,6 +47,10 @@ def datasets(self) -> list[CatalogDataset]:
4647
def facts(self) -> list[CatalogFact]:
4748
return [f for d in self._datasets for f in d.facts]
4849

50+
@property
51+
def aggregated_facts(self) -> list[CatalogAggregatedFact]:
52+
return [f for d in self._datasets for f in d.aggregated_facts]
53+
4954
@property
5055
def attributes(self) -> list[CatalogAttribute]:
5156
return [a for d in self._datasets for a in d.attributes]

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

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2376,6 +2376,70 @@
23762376
],
23772377
"title": "Campaign channels"
23782378
},
2379+
{
2380+
"attributes": [
2381+
{
2382+
"description": "Category Agg",
2383+
"id": "campaign_channels.category_agg",
2384+
"sourceColumn": "category",
2385+
"sourceColumnDataType": "STRING",
2386+
"labels": [],
2387+
"tags": [
2388+
"Campaign channels"
2389+
],
2390+
"title": "Category"
2391+
}
2392+
],
2393+
"description": "Campaign channels per categories",
2394+
"facts": [],
2395+
"aggregatedFacts": [
2396+
{
2397+
"description": "Budget Agg",
2398+
"id": "budget_agg",
2399+
"sourceColumn": "budget",
2400+
"sourceColumnDataType": "INT",
2401+
"tags": [
2402+
"Campaign channels per category"
2403+
],
2404+
"sourceFactReference": {
2405+
"reference": {
2406+
"id": "budget",
2407+
"type": "fact"
2408+
},
2409+
"operation": "SUM"
2410+
}
2411+
}
2412+
],
2413+
"grain": [
2414+
{
2415+
"id": "campaign_channels.category_agg",
2416+
"type": "attribute"
2417+
}
2418+
],
2419+
"id": "campaign_channels_per_category",
2420+
"precedence": 1,
2421+
"references": [
2422+
{
2423+
"identifier": {
2424+
"id": "campaign_channels",
2425+
"type": "dataset"
2426+
},
2427+
"multivalue": false,
2428+
"sourceColumns": [
2429+
"campaign_channel_category"
2430+
],
2431+
"sourceColumnDataTypes": [ "STRING" ]
2432+
}
2433+
],
2434+
"tags": [
2435+
"Campaign channels per category"
2436+
],
2437+
"sql": {
2438+
"statement": "SELECT category, SUM(budget) FROM campaign_channels GROUP BY category",
2439+
"dataSourceId": "demo-test-ds"
2440+
},
2441+
"title": "Campaign channels per category"
2442+
},
23792443
{
23802444
"attributes": [
23812445
{
@@ -2412,6 +2476,7 @@
24122476
},
24132477
"description": "Campaigns",
24142478
"facts": [],
2479+
"aggregatedFacts": [],
24152480
"grain": [
24162481
{
24172482
"id": "campaign_id",
@@ -2494,6 +2559,7 @@
24942559
},
24952560
"description": "Customers",
24962561
"facts": [],
2562+
"aggregatedFacts": [],
24972563
"grain": [
24982564
{
24992565
"id": "customer_id",
@@ -2575,6 +2641,7 @@
25752641
"title": "Quantity"
25762642
}
25772643
],
2644+
"aggregatedFacts": [],
25782645
"grain": [
25792646
{
25802647
"id": "order_line_id",
@@ -2724,6 +2791,7 @@
27242791
},
27252792
"description": "Products",
27262793
"facts": [],
2794+
"aggregatedFacts": [],
27272795
"grain": [
27282796
{
27292797
"id": "product_id",
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
# (C) 2025 GoodData Corporation
2+
grain:
3+
- id: campaign_channels.category_agg
4+
type: attribute
5+
id: campaign_channels_per_category
6+
references:
7+
- identifier:
8+
id: campaign_channels
9+
type: dataset
10+
multivalue: false
11+
sources:
12+
- column: campaign_channel_category
13+
target:
14+
id: campaign_channel_id
15+
type: attribute
16+
dataType: STRING
17+
title: Campaign channels per category
18+
description: Campaign channels per categories
19+
attributes:
20+
- id: campaign_channels.category_agg
21+
labels: []
22+
sourceColumn: category
23+
title: Category
24+
sourceColumnDataType: STRING
25+
description: Category Agg
26+
tags:
27+
- Campaign channels
28+
facts: []
29+
aggregatedFacts:
30+
- id: budget_agg
31+
sourceColumn: budget
32+
sourceFactReference:
33+
operation: SUM
34+
reference:
35+
id: budget
36+
type: fact
37+
sourceColumnDataType: INT
38+
description: Budget Agg
39+
tags:
40+
- Campaign channels per category
41+
precedence: 1
42+
sql:
43+
dataSourceId: demo-test-ds
44+
statement: SELECT category, SUM(budget) FROM campaign_channels GROUP
45+
BY category
46+
tags:
47+
- Campaign channels per category
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
# (C) 2025 GoodData Corporation
2+
grain:
3+
- id: campaign_channels.category_agg
4+
type: attribute
5+
id: campaign_channels_per_category
6+
references:
7+
- identifier:
8+
id: campaign_channels
9+
type: dataset
10+
multivalue: false
11+
sources:
12+
- column: campaign_channel_category
13+
target:
14+
id: campaign_channel_id
15+
type: attribute
16+
dataType: STRING
17+
title: Campaign channels per category
18+
description: Campaign channels per categories
19+
attributes:
20+
- id: campaign_channels.category_agg
21+
labels: []
22+
sourceColumn: category
23+
title: Category
24+
sourceColumnDataType: STRING
25+
description: Category Agg
26+
tags:
27+
- Campaign channels
28+
facts: []
29+
aggregatedFacts:
30+
- id: budget_agg
31+
sourceColumn: budget
32+
sourceFactReference:
33+
operation: SUM
34+
reference:
35+
id: budget
36+
type: fact
37+
sourceColumnDataType: INT
38+
description: Budget Agg
39+
tags:
40+
- Campaign channels per category
41+
precedence: 1
42+
sql:
43+
dataSourceId: demo-test-ds
44+
statement: SELECT category, SUM(budget) FROM campaign_channels GROUP
45+
BY category
46+
tags:
47+
- Campaign channels per category

gooddata-sdk/tests/catalog/test_catalog_workspace.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -700,8 +700,7 @@ def test_clone_workspace(test_config):
700700
default_cloned_decl_ws = sdk.catalog_workspace.get_declarative_workspace(default_cloned_ws_id)
701701
assert default_cloned_decl_ws.ldm.datasets[0].data_source_table_id.data_source_id == test_config["data_source2"]
702702
assert default_cloned_decl_ws.ldm.datasets[0].facts[0].source_column == "BUDGET"
703-
# TODO: Add a nontrivial test for agg facts here
704-
assert default_cloned_decl_ws.ldm.datasets[0].aggregated_facts == []
703+
assert default_cloned_decl_ws.ldm.datasets[1].aggregated_facts[0].source_column == "BUDGET"
705704

706705
sdk.catalog_workspace.clone_workspace(
707706
source_ws_id, target_workspace_id=custom_cloned_ws_id, target_workspace_name=custom_cloned_ws_name
@@ -755,7 +754,7 @@ def test_translate_workspace(test_config):
755754
for fact in dataset.facts:
756755
if fact.id == "budget":
757756
assert fact.title == "Rozpočet"
758-
# TODO: Add agg facts here for descriptions?
757+
# TODO: Do for aggregated facts descriptions
759758

760759
# Run second time without translation function. Previous execution created translation file, which is used.
761760
sdk.catalog_workspace.generate_localized_workspaces(

gooddata-sdk/tests/catalog/test_catalog_workspace_content.py

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,7 @@ def test_catalog_list_facts(test_config):
6262
def test_catalog_list_aggregated_facts(test_config):
6363
sdk = GoodDataSdk.create(host_=test_config["host"], token_=test_config["token"])
6464
agg_facts_list = sdk.catalog_workspace_content.get_aggregated_facts_catalog(test_config["workspace"])
65-
# TODO: Add a non-trivial test
66-
assert len(agg_facts_list) == 0
65+
assert len(agg_facts_list) == 1
6766

6867

6968
@gd_vcr.use_cassette(str(_fixtures_dir / "demo_catalog_list_attributes.yaml"))
@@ -128,7 +127,7 @@ def test_load_and_modify_ds_and_put_declarative_ldm(test_config):
128127
sdk.catalog_workspace.create_or_update(workspace)
129128

130129
ldm_e = sdk.catalog_workspace_content.get_declarative_ldm(workspace_id)
131-
ds_e = list(set([d.data_source_table_id.data_source_id for d in ldm_e.ldm.datasets]))
130+
ds_e = list(set([d.data_source_table_id.data_source_id for d in ldm_e.ldm.datasets if d.data_source_table_id]))
132131
assert ds_e == [test_config["data_source"]]
133132

134133
try:
@@ -146,7 +145,7 @@ def test_load_and_modify_ds_and_put_declarative_ldm(test_config):
146145
ldm_e.ldm.modify_mapped_data_source(data_source_mapping=reverse_data_source_mapping)
147146
sdk.catalog_workspace_content.put_declarative_ldm(identifier, ldm_e, validator, standalone_copy=True)
148147
ldm_o = sdk.catalog_workspace_content.get_declarative_ldm(identifier)
149-
ds_o = list(set([d.data_source_table_id.data_source_id for d in ldm_o.ldm.datasets]))
148+
ds_o = list(set([d.data_source_table_id.data_source_id for d in ldm_o.ldm.datasets if d.data_source_table_id]))
150149
assert ds_o == [test_config["data_source"]]
151150
finally:
152151
_refresh_workspaces(sdk)
@@ -165,7 +164,7 @@ def test_load_ldm_and_modify_tables_columns_case(test_config):
165164
assert ldm_e.ldm.datasets[0].data_source_table_id.id == table_id.upper()
166165
assert ldm_e.ldm.datasets[0].attributes[0].source_column == attribute_column.upper()
167166
assert ldm_e.ldm.datasets[0].facts[0].source_column == fact_column.upper()
168-
# TODO: Add agg facts here
167+
assert ldm_e.ldm.datasets[1].aggregated_facts[0].source_column == fact_column.upper()
169168
assert ldm_e.ldm.datasets[0].references[0].source_columns is None
170169
assert ldm_e.ldm.datasets[0].references[0].sources[0].column == reference_column.upper()
171170
# Test chaining approach as well
@@ -177,7 +176,7 @@ def test_load_ldm_and_modify_tables_columns_case(test_config):
177176
assert ldm_o.ldm.datasets[0].data_source_table_id.id == table_id
178177
assert ldm_o.ldm.datasets[0].attributes[0].source_column == attribute_column
179178
assert ldm_o.ldm.datasets[0].facts[0].source_column == fact_column
180-
# TODO: Add agg facts here
179+
assert ldm_o.ldm.datasets[1].aggregated_facts[0].source_column == fact_column
181180
assert ldm_o.ldm.datasets[0].references[0].source_columns is None
182181
assert ldm_e.ldm.datasets[0].references[0].sources[0].column == reference_column
183182

tests-support/fixtures/demo_declarative_hierarchy.json

Lines changed: 75 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2346,6 +2346,70 @@
23462346
],
23472347
"title": "Campaign channels"
23482348
},
2349+
{
2350+
"attributes": [
2351+
{
2352+
"description": "Category Agg",
2353+
"id": "campaign_channels.category_agg",
2354+
"sourceColumn": "category",
2355+
"sourceColumnDataType": "STRING",
2356+
"labels": [],
2357+
"tags": [
2358+
"Campaign channels"
2359+
],
2360+
"title": "Category"
2361+
}
2362+
],
2363+
"description": "Campaign channels per categories",
2364+
"facts": [],
2365+
"aggregatedFacts": [
2366+
{
2367+
"description": "Budget Agg",
2368+
"id": "budget_agg",
2369+
"sourceColumn": "budget",
2370+
"sourceColumnDataType": "INT",
2371+
"tags": [
2372+
"Campaign channels per category"
2373+
],
2374+
"sourceFactReference": {
2375+
"reference": {
2376+
"id": "budget",
2377+
"type": "fact"
2378+
},
2379+
"operation": "SUM"
2380+
}
2381+
}
2382+
],
2383+
"grain": [
2384+
{
2385+
"id": "campaign_channels.category_agg",
2386+
"type": "attribute"
2387+
}
2388+
],
2389+
"id": "campaign_channels_per_category",
2390+
"precedence": 1,
2391+
"references": [
2392+
{
2393+
"identifier": {
2394+
"id": "campaign_channels",
2395+
"type": "dataset"
2396+
},
2397+
"multivalue": false,
2398+
"sourceColumns": [
2399+
"campaign_channel_category"
2400+
],
2401+
"sourceColumnDataTypes": [ "STRING" ]
2402+
}
2403+
],
2404+
"tags": [
2405+
"Campaign channels per category"
2406+
],
2407+
"sql": {
2408+
"statement": "SELECT category, SUM(budget) FROM campaign_channels GROUP BY category",
2409+
"dataSourceId": "demo-test-ds"
2410+
},
2411+
"title": "Campaign channels per category"
2412+
},
23492413
{
23502414
"attributes": [
23512415
{
@@ -2672,11 +2736,21 @@
26722736
"dateInstances": [
26732737
{
26742738
"granularities": [
2739+
"MINUTE",
2740+
"HOUR",
26752741
"DAY",
26762742
"MONTH",
26772743
"QUARTER",
26782744
"WEEK",
2679-
"YEAR"
2745+
"YEAR",
2746+
"MINUTE_OF_HOUR",
2747+
"HOUR_OF_DAY",
2748+
"DAY_OF_WEEK",
2749+
"DAY_OF_MONTH",
2750+
"DAY_OF_YEAR",
2751+
"WEEK_OF_YEAR",
2752+
"MONTH_OF_YEAR",
2753+
"QUARTER_OF_YEAR"
26802754
],
26812755
"granularitiesFormatting": {
26822756
"titleBase": "",

0 commit comments

Comments
 (0)