Skip to content

Commit

Permalink
feat(ingest/looker): update browse paths to align with looker UI (dat…
Browse files Browse the repository at this point in the history
  • Loading branch information
mayurinehate authored Mar 28, 2024
1 parent 140c0f1 commit 4e328c3
Show file tree
Hide file tree
Showing 26 changed files with 2,463 additions and 1,073 deletions.
3 changes: 2 additions & 1 deletion docs/how/updating-datahub.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ This file documents any backwards-incompatible changes in DataHub and assists pe
- #10026 - The dbt `use_compiled_code` option has been removed, because we now support capturing both source and compiled dbt SQL. This can be configured using `include_compiled_code`, which will be default enabled in 0.13.1.
- #10055 - Assertion entities generated by dbt are now associated with the dbt dataset entity, and not the entity in the data warehouse.
- #10090 - For Redshift ingestion, `use_lineage_v2` is now enabled by default.

- #10147 - For looker ingestion, the browse paths for looker Dashboard, Chart, View, Explore have been updated to align with Looker UI. This does not affect URNs or lineage but primarily affects (improves) browsing experience.
-
### Potential Downtime

### Deprecations
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1199,6 +1199,7 @@ class LookerDashboardElement:
type: Optional[str] = None
description: Optional[str] = None
input_fields: Optional[List[InputFieldElement]] = None
folder_path: Optional[str] = None # for independent looks.

def url(self, base_url: str) -> str:
# A dashboard element can use a look or just a raw query against an explore
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,14 +108,14 @@ class LookerCommonConfig(EnvConfigMixin, PlatformInstanceConfigMixin):
)
explore_browse_pattern: LookerNamingPattern = pydantic.Field(
description=f"Pattern for providing browse paths to explores. {LookerNamingPattern.allowed_docstring()}",
default=LookerNamingPattern(pattern="/{env}/{platform}/{project}/explores"),
default=LookerNamingPattern(pattern="/Explore/{project}/{model}"),
)
view_naming_pattern: LookerViewNamingPattern = Field(
LookerViewNamingPattern(pattern="{project}.view.{name}"),
description=f"Pattern for providing dataset names to views. {LookerViewNamingPattern.allowed_docstring()}",
)
view_browse_pattern: LookerViewNamingPattern = Field(
LookerViewNamingPattern(pattern="/{env}/{platform}/{project}/views"),
LookerViewNamingPattern(pattern="/Develop/{project}/{file_path}"),
description=f"Pattern for providing browse paths to views. {LookerViewNamingPattern.allowed_docstring()}",
)
tag_measures_and_dimensions: bool = Field(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -452,6 +452,12 @@ def _get_looker_dashboard_element( # noqa: C901
else:
slug = ""

look_folder_path = None
if element.look.folder is not None:
look_folder_path = self._get_folder_path(
element.look.folder, self.looker_api
)

return LookerDashboardElement(
id=element.id,
title=title,
Expand All @@ -464,6 +470,7 @@ def _get_looker_dashboard_element( # noqa: C901
for exp in explores
],
input_fields=input_fields,
folder_path=look_folder_path,
)

# Failing the above two approaches, pick out details from result_maker
Expand Down Expand Up @@ -524,10 +531,12 @@ def _get_looker_dashboard_element( # noqa: C901
type=element.type,
description=element.subtitle_text,
look_id=element.look_id,
query_slug=element.result_maker.query.slug
if element.result_maker.query is not None
and element.result_maker.query.slug is not None
else "",
query_slug=(
element.result_maker.query.slug
if element.result_maker.query is not None
and element.result_maker.query.slug is not None
else ""
),
upstream_explores=[
LookerExplore(model_name=model, name=exp) for exp in explores
],
Expand Down Expand Up @@ -603,18 +612,29 @@ def _make_chart_metadata_events(
chartUrl=dashboard_element.url(self.source_config.external_base_url or ""),
inputs=dashboard_element.get_view_urns(self.source_config),
customProperties={
"upstream_fields": ",".join(
sorted(set(field.name for field in dashboard_element.input_fields))
"upstream_fields": (
",".join(
sorted(
set(field.name for field in dashboard_element.input_fields)
)
)
if dashboard_element.input_fields
else ""
)
if dashboard_element.input_fields
else ""
},
)
chart_snapshot.aspects.append(chart_info)

if dashboard and dashboard.folder_path is not None:
browse_path = BrowsePathsClass(
paths=[f"/looker/{dashboard.folder_path}/{dashboard.title}"]
paths=[f"/Folders/{dashboard.folder_path}/{dashboard.title}"]
)
chart_snapshot.aspects.append(browse_path)
elif (
dashboard is None and dashboard_element.folder_path is not None
): # independent look
browse_path = BrowsePathsClass(
paths=[f"/Folders/{dashboard_element.folder_path}"]
)
chart_snapshot.aspects.append(browse_path)

Expand Down Expand Up @@ -673,7 +693,7 @@ def _make_dashboard_metadata_events(
dashboard_snapshot.aspects.append(dashboard_info)
if looker_dashboard.folder_path is not None:
browse_path = BrowsePathsClass(
paths=[f"/looker/{looker_dashboard.folder_path}"]
paths=[f"/Folders/{looker_dashboard.folder_path}"]
)
dashboard_snapshot.aspects.append(browse_path)

Expand Down Expand Up @@ -1084,10 +1104,12 @@ def process_dashboard(
looker_dashboard = self._get_looker_dashboard(dashboard_object, self.looker_api)
mces = self._make_dashboard_and_chart_mces(looker_dashboard)
workunits = [
MetadataWorkUnit(id=f"looker-{mce.proposedSnapshot.urn}", mce=mce)
if isinstance(mce, MetadataChangeEvent)
else MetadataWorkUnit(
id=f"looker-{mce.aspectName}-{mce.entityUrn}", mcp=mce
(
MetadataWorkUnit(id=f"looker-{mce.proposedSnapshot.urn}", mce=mce)
if isinstance(mce, MetadataChangeEvent)
else MetadataWorkUnit(
id=f"looker-{mce.aspectName}-{mce.entityUrn}", mcp=mce
)
)
for mce in mces
]
Expand Down Expand Up @@ -1177,12 +1199,7 @@ def extract_independent_looks(self) -> Iterable[MetadataWorkUnit]:
self.reporter.report_stage_start("extract_independent_looks")

logger.debug("Extracting looks not part of Dashboard")
look_fields: List[str] = [
"id",
"title",
"description",
"query_id",
]
look_fields: List[str] = ["id", "title", "description", "query_id", "folder"]
query_fields: List[str] = [
"id",
"view",
Expand Down Expand Up @@ -1227,8 +1244,8 @@ def extract_independent_looks(self) -> Iterable[MetadataWorkUnit]:
subtitle_text=look.description,
look_id=look.id,
dashboard_id=None, # As this is independent look
look=LookWithQuery(query=query),
)
look=LookWithQuery(query=query, folder=look.folder),
),
)

if dashboard_element is not None:
Expand Down
Loading

0 comments on commit 4e328c3

Please sign in to comment.