Skip to content

Commit

Permalink
fix: metric with filter failed
Browse files Browse the repository at this point in the history
Single metric with filter producing empty result failed with index out of bound. This should not happen and an empty dataframe with columns should be returned.

JIRA: PSDK-207
risk: low
  • Loading branch information
hkad98 committed Oct 8, 2024
1 parent 774eb85 commit dc192ab
Show file tree
Hide file tree
Showing 3 changed files with 218 additions and 6 deletions.
8 changes: 3 additions & 5 deletions gooddata-pandas/gooddata_pandas/data_access.py
Original file line number Diff line number Diff line change
Expand Up @@ -312,12 +312,10 @@ def _extract_for_metrics_only(response: ExecutionResponse, cols: list, col_to_me
"""
exec_def = response.exec_def
result = response.read_result(len(exec_def.metrics))
data = dict()
if len(result.data) == 0:
return {col: [] for col in cols}

for col in cols:
data[col] = [result.data[col_to_metric_idx[col]]]

return data
return {col: [result.data[col_to_metric_idx[col]]] for col in cols}


def _find_attribute(attributes: list[CatalogAttribute], id_obj: IdObjType) -> Union[CatalogAttribute, None]:
Expand Down
200 changes: 200 additions & 0 deletions gooddata-pandas/tests/dataframe/fixtures/filtered_empty_df.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,200 @@
# (C) 2024 GoodData Corporation
version: 1
interactions:
- request:
method: POST
uri: http://localhost:3000/api/v1/actions/workspaces/demo/execution/afm/execute
body:
execution:
attributes: []
filters:
- relativeDateFilter:
dataset:
identifier:
id: date
type: dataset
from: 1
granularity: YEAR
to: 2
measures:
- definition:
measure:
item:
identifier:
id: revenue
type: metric
computeRatio: false
filters: []
localIdentifier: m_revenue
resultSpec:
dimensions:
- itemIdentifiers:
- measureGroup
localIdentifier: dim_0
headers:
Accept:
- application/json
Accept-Encoding:
- br, gzip, deflate
Content-Type:
- application/json
X-GDC-VALIDATE-RELATIONS:
- 'true'
X-Requested-With:
- XMLHttpRequest
response:
status:
code: 200
message: OK
headers:
Access-Control-Allow-Credentials:
- 'true'
Access-Control-Expose-Headers:
- Content-Disposition, Content-Length, Content-Range, Set-Cookie
Cache-Control:
- no-cache, no-store, max-age=0, must-revalidate
Connection:
- keep-alive
Content-Security-Policy:
- 'default-src ''self'' *.wistia.com *.wistia.net; script-src ''self'' ''unsafe-inline''
''unsafe-eval'' *.wistia.com *.wistia.net *.hsforms.net *.hsforms.com
src.litix.io matomo.anywhere.gooddata.com *.jquery.com unpkg.com cdnjs.cloudflare.com;
img-src * data: blob:; style-src ''self'' ''unsafe-inline'' fonts.googleapis.com
cdn.jsdelivr.net fast.fonts.net; font-src ''self'' data: fonts.gstatic.com
*.alicdn.com *.wistia.com cdn.jsdelivr.net info.gooddata.com; frame-src
''self'' *.hsforms.net *.hsforms.com; object-src ''none''; worker-src
''self'' blob:; child-src blob:; connect-src ''self'' *.tiles.mapbox.com
*.mapbox.com *.litix.io *.wistia.com *.hsforms.net *.hsforms.com embedwistia-a.akamaihd.net
matomo.anywhere.gooddata.com; media-src ''self'' blob: data: *.wistia.com
*.wistia.net embedwistia-a.akamaihd.net'
Content-Type:
- application/json
DATE: &id001
- PLACEHOLDER
Expires:
- '0'
GoodData-Deployment:
- aio
Permission-Policy:
- geolocation 'none'; midi 'none'; sync-xhr 'none'; microphone 'none'; camera
'none'; magnetometer 'none'; gyroscope 'none'; fullscreen 'none'; payment
'none';
Pragma:
- no-cache
Referrer-Policy:
- no-referrer
Server:
- nginx
Transfer-Encoding:
- chunked
Vary:
- Origin
- Access-Control-Request-Method
- Access-Control-Request-Headers
X-Content-Type-Options:
- nosniff
X-GDC-TRACE-ID: *id001
X-XSS-Protection:
- '0'
content-length:
- '307'
set-cookie:
- SPRING_REDIRECT_URI=; Max-Age=0; Expires=Tue, 08 Oct 2024 13:35:16 GMT;
Path=/; HTTPOnly; SameSite=Lax
body:
string:
executionResponse:
dimensions:
- headers:
- measureGroupHeaders:
- localIdentifier: m_revenue
format: $#,##0
name: Revenue
localIdentifier: dim_0
links:
executionResult: a8a633b8ec1bc44a3007020033d582740a2a95b7:6e97188bfff240406a2b583fe6e4065f304eb2250a658fcf497dc142a3377e80
- request:
method: GET
uri: http://localhost:3000/api/v1/actions/workspaces/demo/execution/afm/execute/result/a8a633b8ec1bc44a3007020033d582740a2a95b7%3A6e97188bfff240406a2b583fe6e4065f304eb2250a658fcf497dc142a3377e80?offset=0&limit=1
body: null
headers:
Accept:
- application/json
Accept-Encoding:
- br, gzip, deflate
X-GDC-VALIDATE-RELATIONS:
- 'true'
X-Requested-With:
- XMLHttpRequest
response:
status:
code: 200
message: OK
headers:
Access-Control-Allow-Credentials:
- 'true'
Access-Control-Expose-Headers:
- Content-Disposition, Content-Length, Content-Range, Set-Cookie
Cache-Control:
- no-cache, no-store, max-age=0, must-revalidate
Connection:
- keep-alive
Content-Security-Policy:
- 'default-src ''self'' *.wistia.com *.wistia.net; script-src ''self'' ''unsafe-inline''
''unsafe-eval'' *.wistia.com *.wistia.net *.hsforms.net *.hsforms.com
src.litix.io matomo.anywhere.gooddata.com *.jquery.com unpkg.com cdnjs.cloudflare.com;
img-src * data: blob:; style-src ''self'' ''unsafe-inline'' fonts.googleapis.com
cdn.jsdelivr.net fast.fonts.net; font-src ''self'' data: fonts.gstatic.com
*.alicdn.com *.wistia.com cdn.jsdelivr.net info.gooddata.com; frame-src
''self'' *.hsforms.net *.hsforms.com; object-src ''none''; worker-src
''self'' blob:; child-src blob:; connect-src ''self'' *.tiles.mapbox.com
*.mapbox.com *.litix.io *.wistia.com *.hsforms.net *.hsforms.com embedwistia-a.akamaihd.net
matomo.anywhere.gooddata.com; media-src ''self'' blob: data: *.wistia.com
*.wistia.net embedwistia-a.akamaihd.net'
Content-Type:
- application/json
DATE: *id001
Expires:
- '0'
GoodData-Deployment:
- aio
Permission-Policy:
- geolocation 'none'; midi 'none'; sync-xhr 'none'; microphone 'none'; camera
'none'; magnetometer 'none'; gyroscope 'none'; fullscreen 'none'; payment
'none';
Pragma:
- no-cache
Referrer-Policy:
- no-referrer
Server:
- nginx
Transfer-Encoding:
- chunked
Vary:
- Origin
- Access-Control-Request-Method
- Access-Control-Request-Headers
X-Content-Type-Options:
- nosniff
X-GDC-TRACE-ID: *id001
X-XSS-Protection:
- '0'
content-length:
- '131'
set-cookie:
- SPRING_REDIRECT_URI=; Max-Age=0; Expires=Tue, 08 Oct 2024 13:35:16 GMT;
Path=/; HTTPOnly; SameSite=Lax
body:
string:
data: []
dimensionHeaders:
- headerGroups:
- headers: []
grandTotals: []
paging:
count:
- 0
offset:
- 0
total:
- 0
16 changes: 15 additions & 1 deletion gooddata-pandas/tests/dataframe/test_not_indexed_dataframe.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from pathlib import Path

from gooddata_pandas import DataFrameFactory
from gooddata_sdk import PositiveAttributeFilter
from gooddata_sdk import ObjId, PositiveAttributeFilter, RelativeDateFilter, SimpleMetric
from tests_support.vcrpy_utils import get_vcr

gd_vcr = get_vcr()
Expand Down Expand Up @@ -75,3 +75,17 @@ def test_empty_not_indexed_dataframe(gdf: DataFrameFactory):
assert df.columns[0] == "product_name"
assert df.columns[1] == "amount_of_top_customers"
assert df.columns[2] == "total_revenue"


@gd_vcr.use_cassette(str(_fixtures_dir / "filtered_empty_df.yaml"))
def test_filter_empty_df(gdf: DataFrameFactory):
my_metric = SimpleMetric(local_id="m_revenue", item=ObjId(id="revenue", type="metric"))
my_filter = RelativeDateFilter(
dataset=ObjId(id="date", type="dataset"),
granularity="YEAR",
from_shift=1,
to_shift=2,
)
df = gdf.not_indexed(columns=dict(my_metric=my_metric), filter_by=[my_filter])
assert df.empty
assert df.columns[0] == "my_metric"

0 comments on commit dc192ab

Please sign in to comment.