feat(ingestion): powerbi # uniquly identify the multiple instance of same platform (#7632)

Co-authored-by: MohdSiddiqueBagwan <mohdsiddique.bagwan@gslab.com>
Co-authored-by: John Joyce <john@acryl.io>
This commit is contained in:
mohdsiddique 2023-03-21 21:57:29 +05:30 committed by GitHub
parent 7efac2215d
commit 6d6d59141e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 1440 additions and 188 deletions

View File

@ -3,30 +3,42 @@ source:
config: config:
# Your Power BI tenant identifier # Your Power BI tenant identifier
tenant_id: a949d688-67c0-4bf1-a344-e939411c6c0a tenant_id: a949d688-67c0-4bf1-a344-e939411c6c0a
# Azure AD Application identifier
client_id: foo
# Azure AD App client secret
client_secret: bar
# Ingest elements of below PowerBi Workspace into Datahub # Ingest elements of below PowerBi Workspace into Datahub
workspace_id_pattern: workspace_id_pattern:
allow: allow:
- 4bd10256-e999-45dd-8e56-571c77153a5f - 4bd10256-e999-45dd-8e56-571c77153a5f
deny: deny:
# Workspaces dataset environments (PROD, DEV, QA, STAGE)
env: DEV # Enable / Disable ingestion of ownership information for dashboards
# Azure AD Application identifier
client_id: foo
# Azure AD App client secret
client_secret: bar
# Enable / Disable ingestion of user information for dashboards
extract_ownership: true extract_ownership: true
# Enable/Disable extracting workspace information to DataHub containers # Enable/Disable extracting workspace information to DataHub containers
extract_workspaces_to_containers: true extract_workspaces_to_containers: true
# Enable / Disable ingestion of endorsements. # Enable / Disable ingestion of endorsements.
# Please notice that this may overwrite any existing tags defined to ingested entities! # Please notice that this may overwrite any existing tags defined to ingested entities!
extract_endorsements_to_tags: false extract_endorsements_to_tags: false
# dataset_type_mapping is fixed mapping of Power BI datasources type to equivalent Datahub "data platform" dataset
dataset_type_mapping: # Optional -- This mapping is optional and only required to configure platform-instance for upstream tables
PostgreSql: postgres # A mapping of PowerBI datasource's server i.e host[:port] to data platform instance.
Oracle: oracle # :port is optional and only needed if your datasource server is running on non-standard port.
Sql: mssql # For Google BigQuery the datasource's server is google bigquery project name
GoogleBigQuery: bigquery server_to_platform_instance:
ap-south-1.snowflakecomputing.com:
platform_instance: operational_instance
env: DEV
oracle-server:1920:
platform_instance: high_performance_production_unit
env: PROD
big-query-sales-project:
platform_instance: sn-2
env: QA
sink: sink:
# sink configs # sink configs

View File

@ -1,5 +1,6 @@
import logging import logging
from dataclasses import dataclass, field as dataclass_field from dataclasses import dataclass, field as dataclass_field
from enum import Enum
from typing import Dict, List, Optional, Union from typing import Dict, List, Optional, Union
import pydantic import pydantic
@ -7,7 +8,8 @@ from pydantic import validator
from pydantic.class_validators import root_validator from pydantic.class_validators import root_validator
import datahub.emitter.mce_builder as builder import datahub.emitter.mce_builder as builder
from datahub.configuration.common import AllowDenyPattern from datahub.configuration.common import AllowDenyPattern, ConfigModel
from datahub.configuration.pydantic_field_deprecation import pydantic_field_deprecated
from datahub.configuration.source_common import DEFAULT_ENV, DatasetSourceConfigMixin from datahub.configuration.source_common import DEFAULT_ENV, DatasetSourceConfigMixin
from datahub.ingestion.source.common.subtypes import BIAssetSubTypes from datahub.ingestion.source.common.subtypes import BIAssetSubTypes
from datahub.ingestion.source.state.stale_entity_removal_handler import ( from datahub.ingestion.source.state.stale_entity_removal_handler import (
@ -105,6 +107,40 @@ class Constant:
DATASET_WEB_URL = "datasetWebUrl" DATASET_WEB_URL = "datasetWebUrl"
@dataclass
class DataPlatformPair:
datahub_data_platform_name: str
powerbi_data_platform_name: str
class SupportedDataPlatform(Enum):
POSTGRES_SQL = DataPlatformPair(
powerbi_data_platform_name="PostgreSQL", datahub_data_platform_name="postgres"
)
ORACLE = DataPlatformPair(
powerbi_data_platform_name="Oracle", datahub_data_platform_name="oracle"
)
SNOWFLAKE = DataPlatformPair(
powerbi_data_platform_name="Snowflake", datahub_data_platform_name="snowflake"
)
MS_SQL = DataPlatformPair(
powerbi_data_platform_name="Sql", datahub_data_platform_name="mssql"
)
GOOGLE_BIGQUERY = DataPlatformPair(
powerbi_data_platform_name="GoogleBigQuery",
datahub_data_platform_name="bigquery",
)
AMAZON_REDSHIFT = DataPlatformPair(
powerbi_data_platform_name="AmazonRedshift",
datahub_data_platform_name="redshift",
)
@dataclass @dataclass
class PowerBiDashboardSourceReport(StaleEntityRemovalSourceReport): class PowerBiDashboardSourceReport(StaleEntityRemovalSourceReport):
dashboards_scanned: int = 0 dashboards_scanned: int = 0
@ -129,15 +165,26 @@ class PowerBiDashboardSourceReport(StaleEntityRemovalSourceReport):
self.number_of_workspaces = number_of_workspaces self.number_of_workspaces = number_of_workspaces
@dataclass def default_for_dataset_type_mapping() -> Dict[str, str]:
class PlatformDetail: dict_: dict = {}
for item in SupportedDataPlatform:
dict_[
item.value.powerbi_data_platform_name
] = item.value.datahub_data_platform_name
return dict_
class PlatformDetail(ConfigModel):
platform_instance: Optional[str] = pydantic.Field( platform_instance: Optional[str] = pydantic.Field(
default=None, default=None,
description="DataHub platform instance name. It should be same as you have used in ingestion receipe of DataHub platform ingestion source of particular platform", description="DataHub platform instance name. To generate correct urn for upstream dataset, this should match "
"with platform instance name used in ingestion"
"recipe of other datahub sources.",
) )
env: str = pydantic.Field( env: str = pydantic.Field(
default=DEFAULT_ENV, default=DEFAULT_ENV,
description="The environment that all assets produced by DataHub platform ingestion source belong to", description="The environment that the platform is located in. It is default to PROD",
) )
@ -157,7 +204,9 @@ class PowerBiDashboardSourceConfig(
tenant_id: str = pydantic.Field(description="PowerBI tenant identifier") tenant_id: str = pydantic.Field(description="PowerBI tenant identifier")
# PowerBi workspace identifier # PowerBi workspace identifier
workspace_id: Optional[str] = pydantic.Field( workspace_id: Optional[str] = pydantic.Field(
description="[deprecated] Use workspace_id_pattern instead", default=None default=None,
description="[deprecated] Use workspace_id_pattern instead",
hidden_from_docs=True,
) )
# PowerBi workspace identifier # PowerBi workspace identifier
workspace_id_pattern: AllowDenyPattern = pydantic.Field( workspace_id_pattern: AllowDenyPattern = pydantic.Field(
@ -171,7 +220,23 @@ class PowerBiDashboardSourceConfig(
dataset_type_mapping: Union[ dataset_type_mapping: Union[
Dict[str, str], Dict[str, PlatformDetail] Dict[str, str], Dict[str, PlatformDetail]
] = pydantic.Field( ] = pydantic.Field(
description="Mapping of PowerBI datasource type to DataHub supported data-sources. See Quickstart Recipe for mapping" default_factory=default_for_dataset_type_mapping,
description="[deprecated] Use server_to_platform_instance instead. Mapping of PowerBI datasource type to "
"DataHub supported datasources."
"You can configured platform instance for dataset lineage. "
"See Quickstart Recipe for mapping",
hidden_from_docs=True,
)
# PowerBI datasource's server to platform instance mapping
server_to_platform_instance: Dict[str, PlatformDetail] = pydantic.Field(
default={},
description="A mapping of PowerBI datasource's server i.e host[:port] to Data platform instance."
" :port is optional and only needed if your datasource server is running on non-standard port."
"For Google BigQuery the datasource's server is google bigquery project name",
)
# deprecated warning
_dataset_type_mapping = pydantic_field_deprecated(
"dataset_type_mapping", "server_to_platform_instance"
) )
# Azure app client identifier # Azure app client identifier
client_id: str = pydantic.Field(description="Azure app client identifier") client_id: str = pydantic.Field(description="Azure app client identifier")
@ -259,14 +324,28 @@ class PowerBiDashboardSourceConfig(
if workspace_id_pattern == AllowDenyPattern.allow_all() and workspace_id: if workspace_id_pattern == AllowDenyPattern.allow_all() and workspace_id:
logger.warning( logger.warning(
"workspace_id_pattern is not set but workspace_id is set, setting workspace_id as workspace_id_pattern. workspace_id will be deprecated, please use workspace_id_pattern instead." "workspace_id_pattern is not set but workspace_id is set, setting workspace_id as "
"workspace_id_pattern. workspace_id will be deprecated, please use workspace_id_pattern instead."
) )
values["workspace_id_pattern"] = AllowDenyPattern( values["workspace_id_pattern"] = AllowDenyPattern(
allow=[f"^{workspace_id}$"] allow=[f"^{workspace_id}$"]
) )
elif workspace_id_pattern != AllowDenyPattern.allow_all() and workspace_id: elif workspace_id_pattern != AllowDenyPattern.allow_all() and workspace_id:
logger.warning( logger.warning(
"workspace_id will be ignored in favour of workspace_id_pattern. workspace_id will be deprecated, please use workspace_id_pattern only." "workspace_id will be ignored in favour of workspace_id_pattern. workspace_id will be deprecated, "
"please use workspace_id_pattern only."
) )
values.pop("workspace_id") values.pop("workspace_id")
return values return values
@root_validator(pre=True)
def raise_error_for_dataset_type_mapping(cls, values: Dict) -> Dict:
if (
values.get("dataset_type_mapping") is not None
and values.get("server_to_platform_instance") is not None
):
raise ValueError(
"dataset_type_mapping is deprecated. Use server_to_platform_instance only."
)
return values

View File

@ -0,0 +1,75 @@
import logging
from abc import ABC, abstractmethod
from typing import Union
from datahub.ingestion.source.powerbi.config import (
PlatformDetail,
PowerBiDashboardSourceConfig,
)
from datahub.ingestion.source.powerbi.m_query.resolver import DataPlatformTable
logger = logging.getLogger(__name__)
class AbstractDataPlatformInstanceResolver(ABC):
@abstractmethod
def get_platform_instance(
self, dataplatform_table: DataPlatformTable
) -> PlatformDetail:
pass
class BaseAbstractDataPlatformInstanceResolver(
AbstractDataPlatformInstanceResolver, ABC
):
config: PowerBiDashboardSourceConfig
def __init__(self, config):
self.config = config
class ResolvePlatformInstanceFromDatasetTypeMapping(
BaseAbstractDataPlatformInstanceResolver
):
def get_platform_instance(
self, dataplatform_table: DataPlatformTable
) -> PlatformDetail:
platform: Union[str, PlatformDetail] = self.config.dataset_type_mapping[
dataplatform_table.data_platform_pair.powerbi_data_platform_name
]
if isinstance(platform, PlatformDetail):
return platform
return PlatformDetail.parse_obj({})
class ResolvePlatformInstanceFromServerToPlatformInstance(
BaseAbstractDataPlatformInstanceResolver
):
def get_platform_instance(
self, dataplatform_table: DataPlatformTable
) -> PlatformDetail:
return (
self.config.server_to_platform_instance[
dataplatform_table.datasource_server
]
if dataplatform_table.datasource_server
in self.config.server_to_platform_instance
else PlatformDetail.parse_obj({})
)
def create_dataplatform_instance_resolver(
config: PowerBiDashboardSourceConfig,
) -> AbstractDataPlatformInstanceResolver:
if config.server_to_platform_instance:
logger.debug(
"Creating resolver to resolve platform instance from server_to_platform_instance"
)
return ResolvePlatformInstanceFromServerToPlatformInstance(config)
logger.debug(
"Creating resolver to resolve platform instance from dataset_type_mapping"
)
return ResolvePlatformInstanceFromDatasetTypeMapping(config)

View File

@ -6,7 +6,11 @@ from typing import Any, Dict, List, Optional, Tuple, Type, Union, cast
from lark import Tree from lark import Tree
from datahub.ingestion.source.powerbi.config import PowerBiDashboardSourceReport from datahub.ingestion.source.powerbi.config import (
DataPlatformPair,
PowerBiDashboardSourceReport,
SupportedDataPlatform,
)
from datahub.ingestion.source.powerbi.m_query import native_sql_parser, tree_function from datahub.ingestion.source.powerbi.m_query import native_sql_parser, tree_function
from datahub.ingestion.source.powerbi.m_query.data_classes import ( from datahub.ingestion.source.powerbi.m_query.data_classes import (
TRACE_POWERBI_MQUERY_PARSER, TRACE_POWERBI_MQUERY_PARSER,
@ -18,52 +22,19 @@ from datahub.ingestion.source.powerbi.rest_api_wrapper.data_classes import Table
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@dataclass
class DataPlatformPair:
datahub_data_platform_name: str
powerbi_data_platform_name: str
@dataclass @dataclass
class DataPlatformTable: class DataPlatformTable:
name: str name: str
full_name: str full_name: str
datasource_server: str
data_platform_pair: DataPlatformPair data_platform_pair: DataPlatformPair
class SupportedDataPlatform(Enum): class AbstractDataPlatformTableCreator(ABC):
POSTGRES_SQL = DataPlatformPair(
powerbi_data_platform_name="PostgreSQL", datahub_data_platform_name="postgres"
)
ORACLE = DataPlatformPair(
powerbi_data_platform_name="Oracle", datahub_data_platform_name="oracle"
)
SNOWFLAKE = DataPlatformPair(
powerbi_data_platform_name="Snowflake", datahub_data_platform_name="snowflake"
)
MS_SQL = DataPlatformPair(
powerbi_data_platform_name="Sql", datahub_data_platform_name="mssql"
)
GOOGLE_BIGQUERY = DataPlatformPair(
powerbi_data_platform_name="GoogleBigQuery",
datahub_data_platform_name="bigquery",
)
AMAZON_REDSHIFT = DataPlatformPair(
powerbi_data_platform_name="AmazonRedshift",
datahub_data_platform_name="redshift",
)
class AbstractTableFullNameCreator(ABC):
@abstractmethod @abstractmethod
def get_full_table_names( def create_dataplatform_tables(
self, data_access_func_detail: DataAccessFunctionDetail self, data_access_func_detail: DataAccessFunctionDetail
) -> List[str]: ) -> List[DataPlatformTable]:
pass pass
@abstractmethod @abstractmethod
@ -71,19 +42,20 @@ class AbstractTableFullNameCreator(ABC):
pass pass
@staticmethod @staticmethod
def get_db_name_from_second_argument(arg_list: Tree) -> Optional[str]: def get_db_detail_from_argument(
arg_list: Tree,
) -> Tuple[Optional[str], Optional[str]]:
arguments: List[str] = tree_function.strip_char_from_list( arguments: List[str] = tree_function.strip_char_from_list(
values=tree_function.remove_whitespaces_from_list( values=tree_function.remove_whitespaces_from_list(
tree_function.token_values(arg_list) tree_function.token_values(arg_list)
), ),
char='"',
) )
if len(arguments) < 2: if len(arguments) < 2:
logger.debug(f"Expected minimum 2 arguments, but got {len(arguments)}") logger.debug(f"Expected minimum 2 arguments, but got {len(arguments)}")
return None return None, None
return arguments[1] return arguments[0], arguments[1]
class AbstractDataAccessMQueryResolver(ABC): class AbstractDataAccessMQueryResolver(ABC):
@ -140,7 +112,6 @@ class MQueryResolver(AbstractDataAccessMQueryResolver, ABC):
cast(Tree, item_selector), parameters=self.parameters cast(Tree, item_selector), parameters=self.parameters
) )
), ),
'"',
) )
identifier: List[str] = tree_function.token_values( identifier: List[str] = tree_function.token_values(
cast(Tree, identifier_tree) cast(Tree, identifier_tree)
@ -382,25 +353,18 @@ class MQueryResolver(AbstractDataAccessMQueryResolver, ABC):
) )
continue continue
table_full_name_creator: AbstractTableFullNameCreator = ( table_full_name_creator: AbstractDataPlatformTableCreator = (
supported_resolver.get_table_full_name_creator()() supported_resolver.get_table_full_name_creator()()
) )
for table_full_name in table_full_name_creator.get_full_table_names( data_platform_tables.extend(
f_detail table_full_name_creator.create_dataplatform_tables(f_detail)
):
data_platform_tables.append(
DataPlatformTable(
name=table_full_name.split(".")[-1],
full_name=table_full_name,
data_platform_pair=table_full_name_creator.get_platform_pair(),
)
) )
return data_platform_tables return data_platform_tables
class DefaultTwoStepDataAccessSources(AbstractTableFullNameCreator, ABC): class DefaultTwoStepDataAccessSources(AbstractDataPlatformTableCreator, ABC):
""" """
These are the DataSource for which PowerBI Desktop generates default M-Query of following pattern These are the DataSource for which PowerBI Desktop generates default M-Query of following pattern
let let
@ -412,19 +376,16 @@ class DefaultTwoStepDataAccessSources(AbstractTableFullNameCreator, ABC):
def two_level_access_pattern( def two_level_access_pattern(
self, data_access_func_detail: DataAccessFunctionDetail self, data_access_func_detail: DataAccessFunctionDetail
) -> List[str]: ) -> List[DataPlatformTable]:
full_table_names: List[str] = []
logger.debug( logger.debug(
f"Processing {self.get_platform_pair().powerbi_data_platform_name} function detail {data_access_func_detail}" f"Processing {self.get_platform_pair().powerbi_data_platform_name} data-access function detail {data_access_func_detail}"
) )
db_name: Optional[str] = self.get_db_name_from_second_argument( server, db_name = self.get_db_detail_from_argument(
data_access_func_detail.arg_list data_access_func_detail.arg_list
) )
if db_name is None: if server is None or db_name is None:
logger.debug("db_name not found in expression") return [] # Return empty list
return full_table_names # Return empty list
schema_name: str = cast( schema_name: str = cast(
IdentifierAccessor, data_access_func_detail.identifier_accessor IdentifierAccessor, data_access_func_detail.identifier_accessor
@ -434,38 +395,44 @@ class DefaultTwoStepDataAccessSources(AbstractTableFullNameCreator, ABC):
IdentifierAccessor, data_access_func_detail.identifier_accessor IdentifierAccessor, data_access_func_detail.identifier_accessor
).items["Item"] ).items["Item"]
full_table_names.append(f"{db_name}.{schema_name}.{table_name}") full_table_name: str = f"{db_name}.{schema_name}.{table_name}"
logger.debug( logger.debug(
f"Platform({self.get_platform_pair().datahub_data_platform_name}) full-table-names = {full_table_names}" f"Platform({self.get_platform_pair().datahub_data_platform_name}) full_table_name= {full_table_name}"
) )
return full_table_names return [
DataPlatformTable(
name=table_name,
full_name=full_table_name,
datasource_server=server,
data_platform_pair=self.get_platform_pair(),
)
]
class PostgresTableFullNameCreator(DefaultTwoStepDataAccessSources): class PostgresDataPlatformTableCreator(DefaultTwoStepDataAccessSources):
def get_full_table_names( def create_dataplatform_tables(
self, data_access_func_detail: DataAccessFunctionDetail self, data_access_func_detail: DataAccessFunctionDetail
) -> List[str]: ) -> List[DataPlatformTable]:
return self.two_level_access_pattern(data_access_func_detail) return self.two_level_access_pattern(data_access_func_detail)
def get_platform_pair(self) -> DataPlatformPair: def get_platform_pair(self) -> DataPlatformPair:
return SupportedDataPlatform.POSTGRES_SQL.value return SupportedDataPlatform.POSTGRES_SQL.value
class MSSqlTableFullNameCreator(DefaultTwoStepDataAccessSources): class MSSqlDataPlatformTableCreator(DefaultTwoStepDataAccessSources):
def get_platform_pair(self) -> DataPlatformPair: def get_platform_pair(self) -> DataPlatformPair:
return SupportedDataPlatform.MS_SQL.value return SupportedDataPlatform.MS_SQL.value
def get_full_table_names( def create_dataplatform_tables(
self, data_access_func_detail: DataAccessFunctionDetail self, data_access_func_detail: DataAccessFunctionDetail
) -> List[str]: ) -> List[DataPlatformTable]:
full_table_names: List[str] = [] dataplatform_tables: List[DataPlatformTable] = []
arguments: List[str] = tree_function.strip_char_from_list( arguments: List[str] = tree_function.strip_char_from_list(
values=tree_function.remove_whitespaces_from_list( values=tree_function.remove_whitespaces_from_list(
tree_function.token_values(data_access_func_detail.arg_list) tree_function.token_values(data_access_func_detail.arg_list)
), ),
char='"',
) )
if len(arguments) == 2: if len(arguments) == 2:
@ -475,9 +442,10 @@ class MSSqlTableFullNameCreator(DefaultTwoStepDataAccessSources):
if len(arguments) >= 4 and arguments[2] != "Query": if len(arguments) >= 4 and arguments[2] != "Query":
logger.debug("Unsupported case is found. Second index is not the Query") logger.debug("Unsupported case is found. Second index is not the Query")
return full_table_names return dataplatform_tables
db_name: str = arguments[1] db_name: str = arguments[1]
tables: List[str] = native_sql_parser.get_tables(arguments[3]) tables: List[str] = native_sql_parser.get_tables(arguments[3])
for table in tables: for table in tables:
schema_and_table: List[str] = table.split(".") schema_and_table: List[str] = table.split(".")
@ -486,34 +454,42 @@ class MSSqlTableFullNameCreator(DefaultTwoStepDataAccessSources):
# https://learn.microsoft.com/en-us/sql/relational-databases/security/authentication-access/ownership-and-user-schema-separation?view=sql-server-ver16 # https://learn.microsoft.com/en-us/sql/relational-databases/security/authentication-access/ownership-and-user-schema-separation?view=sql-server-ver16
schema_and_table.insert(0, "dbo") schema_and_table.insert(0, "dbo")
full_table_names.append( dataplatform_tables.append(
f"{db_name}.{schema_and_table[0]}.{schema_and_table[1]}" DataPlatformTable(
name=schema_and_table[1],
full_name=f"{db_name}.{schema_and_table[0]}.{schema_and_table[1]}",
datasource_server=arguments[0],
data_platform_pair=self.get_platform_pair(),
)
) )
logger.debug("MS-SQL full-table-names %s", full_table_names) logger.debug("MS-SQL full-table-names %s", dataplatform_tables)
return full_table_names return dataplatform_tables
class OracleTableFullNameCreator(AbstractTableFullNameCreator): class OracleDataPlatformTableCreator(AbstractDataPlatformTableCreator):
def get_platform_pair(self) -> DataPlatformPair: def get_platform_pair(self) -> DataPlatformPair:
return SupportedDataPlatform.ORACLE.value return SupportedDataPlatform.ORACLE.value
def _get_db_name(self, value: str) -> Optional[str]: @staticmethod
error_message: str = f"The target argument ({value}) should in the format of <host-name>:<port>/<db-name>[.<domain>]" def _get_server_and_db_name(value: str) -> Tuple[Optional[str], Optional[str]]:
error_message: str = (
f"The target argument ({value}) should in the format of <host-name>:<port>/<db-name>["
".<domain>]"
)
splitter_result: List[str] = value.split("/") splitter_result: List[str] = value.split("/")
if len(splitter_result) != 2: if len(splitter_result) != 2:
logger.debug(error_message) logger.debug(error_message)
return None return None, None
db_name = splitter_result[1].split(".")[0] db_name = splitter_result[1].split(".")[0]
return db_name return tree_function.strip_char_from_list([splitter_result[0]])[0], db_name
def get_full_table_names( def create_dataplatform_tables(
self, data_access_func_detail: DataAccessFunctionDetail self, data_access_func_detail: DataAccessFunctionDetail
) -> List[str]: ) -> List[DataPlatformTable]:
full_table_names: List[str] = []
logger.debug( logger.debug(
f"Processing Oracle data-access function detail {data_access_func_detail}" f"Processing Oracle data-access function detail {data_access_func_detail}"
@ -523,9 +499,10 @@ class OracleTableFullNameCreator(AbstractTableFullNameCreator):
tree_function.token_values(data_access_func_detail.arg_list) tree_function.token_values(data_access_func_detail.arg_list)
) )
db_name: Optional[str] = self._get_db_name(arguments[0]) server, db_name = self._get_server_and_db_name(arguments[0])
if db_name is None:
return full_table_names if db_name is None or server is None:
return []
schema_name: str = cast( schema_name: str = cast(
IdentifierAccessor, data_access_func_detail.identifier_accessor IdentifierAccessor, data_access_func_detail.identifier_accessor
@ -536,19 +513,32 @@ class OracleTableFullNameCreator(AbstractTableFullNameCreator):
cast(IdentifierAccessor, data_access_func_detail.identifier_accessor).next, cast(IdentifierAccessor, data_access_func_detail.identifier_accessor).next,
).items["Name"] ).items["Name"]
full_table_names.append(f"{db_name}.{schema_name}.{table_name}") return [
DataPlatformTable(
return full_table_names name=table_name,
full_name=f"{db_name}.{schema_name}.{table_name}",
datasource_server=server,
data_platform_pair=self.get_platform_pair(),
)
]
class DefaultThreeStepDataAccessSources(AbstractTableFullNameCreator, ABC): class DefaultThreeStepDataAccessSources(AbstractDataPlatformTableCreator, ABC):
def get_full_table_names( def get_datasource_server(
self, arguments: List[str], data_access_func_detail: DataAccessFunctionDetail
) -> str:
return tree_function.strip_char_from_list([arguments[0]])[0]
def create_dataplatform_tables(
self, data_access_func_detail: DataAccessFunctionDetail self, data_access_func_detail: DataAccessFunctionDetail
) -> List[str]: ) -> List[DataPlatformTable]:
logger.debug( logger.debug(
f"Processing {self.get_platform_pair().datahub_data_platform_name} function detail {data_access_func_detail}" f"Processing {self.get_platform_pair().datahub_data_platform_name} function detail {data_access_func_detail}"
) )
arguments: List[str] = tree_function.remove_whitespaces_from_list(
tree_function.token_values(data_access_func_detail.arg_list)
)
# First is database name # First is database name
db_name: str = data_access_func_detail.identifier_accessor.items["Name"] # type: ignore db_name: str = data_access_func_detail.identifier_accessor.items["Name"] # type: ignore
# Second is schema name # Second is schema name
@ -566,37 +556,56 @@ class DefaultThreeStepDataAccessSources(AbstractTableFullNameCreator, ABC):
f"{self.get_platform_pair().datahub_data_platform_name} full-table-name {full_table_name}" f"{self.get_platform_pair().datahub_data_platform_name} full-table-name {full_table_name}"
) )
return [full_table_name] return [
DataPlatformTable(
name=table_name,
full_name=full_table_name,
datasource_server=self.get_datasource_server(
arguments, data_access_func_detail
),
data_platform_pair=self.get_platform_pair(),
)
]
class SnowflakeTableFullNameCreator(DefaultThreeStepDataAccessSources): class SnowflakeDataPlatformTableCreator(DefaultThreeStepDataAccessSources):
def get_platform_pair(self) -> DataPlatformPair: def get_platform_pair(self) -> DataPlatformPair:
return SupportedDataPlatform.SNOWFLAKE.value return SupportedDataPlatform.SNOWFLAKE.value
class GoogleBigQueryTableFullNameCreator(DefaultThreeStepDataAccessSources): class GoogleBigQueryDataPlatformTableCreator(DefaultThreeStepDataAccessSources):
def get_platform_pair(self) -> DataPlatformPair: def get_platform_pair(self) -> DataPlatformPair:
return SupportedDataPlatform.GOOGLE_BIGQUERY.value return SupportedDataPlatform.GOOGLE_BIGQUERY.value
def get_datasource_server(
self, arguments: List[str], data_access_func_detail: DataAccessFunctionDetail
) -> str:
# In Google BigQuery server is project-name
# condition to silent lint, it is not going to be None
return (
data_access_func_detail.identifier_accessor.items["Name"]
if data_access_func_detail.identifier_accessor is not None
else str()
)
class AmazonRedshiftFullNameCreator(AbstractTableFullNameCreator):
class AmazonRedshiftDataPlatformTableCreator(AbstractDataPlatformTableCreator):
def get_platform_pair(self) -> DataPlatformPair: def get_platform_pair(self) -> DataPlatformPair:
return SupportedDataPlatform.AMAZON_REDSHIFT.value return SupportedDataPlatform.AMAZON_REDSHIFT.value
def get_full_table_names( def create_dataplatform_tables(
self, data_access_func_detail: DataAccessFunctionDetail self, data_access_func_detail: DataAccessFunctionDetail
) -> List[str]: ) -> List[DataPlatformTable]:
full_table_names: List[str] = []
logger.debug( logger.debug(
f"Processing AmazonRedshift data-access function detail {data_access_func_detail}" f"Processing AmazonRedshift data-access function detail {data_access_func_detail}"
) )
db_name: Optional[str] = self.get_db_name_from_second_argument( server, db_name = self.get_db_detail_from_argument(
data_access_func_detail.arg_list data_access_func_detail.arg_list
) )
if db_name is None: if db_name is None or server is None:
return full_table_names # Return empty list return [] # Return empty list
schema_name: str = cast( schema_name: str = cast(
IdentifierAccessor, data_access_func_detail.identifier_accessor IdentifierAccessor, data_access_func_detail.identifier_accessor
@ -607,12 +616,17 @@ class AmazonRedshiftFullNameCreator(AbstractTableFullNameCreator):
cast(IdentifierAccessor, data_access_func_detail.identifier_accessor).next, cast(IdentifierAccessor, data_access_func_detail.identifier_accessor).next,
).items["Name"] ).items["Name"]
full_table_names.append(f"{db_name}.{schema_name}.{table_name}") return [
DataPlatformTable(
return full_table_names name=table_name,
full_name=f"{db_name}.{schema_name}.{table_name}",
datasource_server=server,
data_platform_pair=self.get_platform_pair(),
)
]
class NativeQueryTableFullNameCreator(AbstractTableFullNameCreator): class NativeQueryDataPlatformTableCreator(AbstractDataPlatformTableCreator):
SUPPORTED_NATIVE_QUERY_DATA_PLATFORM: dict = { SUPPORTED_NATIVE_QUERY_DATA_PLATFORM: dict = {
SupportedDataPlatform.SNOWFLAKE.value.powerbi_data_platform_name: SupportedDataPlatform.SNOWFLAKE, SupportedDataPlatform.SNOWFLAKE.value.powerbi_data_platform_name: SupportedDataPlatform.SNOWFLAKE,
SupportedDataPlatform.AMAZON_REDSHIFT.value.powerbi_data_platform_name: SupportedDataPlatform.AMAZON_REDSHIFT, SupportedDataPlatform.AMAZON_REDSHIFT.value.powerbi_data_platform_name: SupportedDataPlatform.AMAZON_REDSHIFT,
@ -626,13 +640,13 @@ class NativeQueryTableFullNameCreator(AbstractTableFullNameCreator):
def is_native_parsing_supported(data_access_function_name: str) -> bool: def is_native_parsing_supported(data_access_function_name: str) -> bool:
return ( return (
data_access_function_name data_access_function_name
in NativeQueryTableFullNameCreator.SUPPORTED_NATIVE_QUERY_DATA_PLATFORM in NativeQueryDataPlatformTableCreator.SUPPORTED_NATIVE_QUERY_DATA_PLATFORM
) )
def get_full_table_names( def create_dataplatform_tables(
self, data_access_func_detail: DataAccessFunctionDetail self, data_access_func_detail: DataAccessFunctionDetail
) -> List[str]: ) -> List[DataPlatformTable]:
full_table_names: List[str] = [] dataplatform_tables: List[DataPlatformTable] = []
t1: Tree = cast( t1: Tree = cast(
Tree, tree_function.first_arg_list_func(data_access_func_detail.arg_list) Tree, tree_function.first_arg_list_func(data_access_func_detail.arg_list)
) )
@ -643,11 +657,11 @@ class NativeQueryTableFullNameCreator(AbstractTableFullNameCreator):
f"Expecting 2 argument, actual argument count is {len(flat_argument_list)}" f"Expecting 2 argument, actual argument count is {len(flat_argument_list)}"
) )
logger.debug(f"Flat argument list = {flat_argument_list}") logger.debug(f"Flat argument list = {flat_argument_list}")
return full_table_names return dataplatform_tables
data_access_tokens: List[str] = tree_function.remove_whitespaces_from_list( data_access_tokens: List[str] = tree_function.remove_whitespaces_from_list(
tree_function.token_values(flat_argument_list[0]) tree_function.token_values(flat_argument_list[0])
) )
if not self.is_native_parsing_supported(data_access_tokens[0]): if not self.is_native_parsing_supported(data_access_tokens[0]):
logger.debug( logger.debug(
f"Unsupported native-query data-platform = {data_access_tokens[0]}" f"Unsupported native-query data-platform = {data_access_tokens[0]}"
@ -655,7 +669,13 @@ class NativeQueryTableFullNameCreator(AbstractTableFullNameCreator):
logger.debug( logger.debug(
f"NativeQuery is supported only for {self.SUPPORTED_NATIVE_QUERY_DATA_PLATFORM}" f"NativeQuery is supported only for {self.SUPPORTED_NATIVE_QUERY_DATA_PLATFORM}"
) )
return full_table_names
if len(data_access_tokens[0]) < 3:
logger.debug(
f"Server is not available in argument list for data-platform {data_access_tokens[0]}. Returning empty "
"list"
)
return dataplatform_tables
self.current_data_platform = self.SUPPORTED_NATIVE_QUERY_DATA_PLATFORM[ self.current_data_platform = self.SUPPORTED_NATIVE_QUERY_DATA_PLATFORM[
data_access_tokens[0] data_access_tokens[0]
@ -665,7 +685,6 @@ class NativeQueryTableFullNameCreator(AbstractTableFullNameCreator):
values=tree_function.remove_whitespaces_from_list( values=tree_function.remove_whitespaces_from_list(
tree_function.token_values(flat_argument_list[1]) tree_function.token_values(flat_argument_list[1])
), ),
char='"',
)[ )[
0 0
] # Remove any whitespaces and double quotes character ] # Remove any whitespaces and double quotes character
@ -677,9 +696,18 @@ class NativeQueryTableFullNameCreator(AbstractTableFullNameCreator):
) )
continue continue
full_table_names.append(table) dataplatform_tables.append(
DataPlatformTable(
name=table.split(".")[2],
full_name=table,
datasource_server=tree_function.strip_char_from_list(
[data_access_tokens[2]]
)[0],
data_platform_pair=self.get_platform_pair(),
)
)
return full_table_names return dataplatform_tables
class FunctionName(Enum): class FunctionName(Enum):
@ -694,41 +722,41 @@ class FunctionName(Enum):
class SupportedResolver(Enum): class SupportedResolver(Enum):
POSTGRES_SQL = ( POSTGRES_SQL = (
PostgresTableFullNameCreator, PostgresDataPlatformTableCreator,
FunctionName.POSTGRESQL_DATA_ACCESS, FunctionName.POSTGRESQL_DATA_ACCESS,
) )
ORACLE = ( ORACLE = (
OracleTableFullNameCreator, OracleDataPlatformTableCreator,
FunctionName.ORACLE_DATA_ACCESS, FunctionName.ORACLE_DATA_ACCESS,
) )
SNOWFLAKE = ( SNOWFLAKE = (
SnowflakeTableFullNameCreator, SnowflakeDataPlatformTableCreator,
FunctionName.SNOWFLAKE_DATA_ACCESS, FunctionName.SNOWFLAKE_DATA_ACCESS,
) )
MS_SQL = ( MS_SQL = (
MSSqlTableFullNameCreator, MSSqlDataPlatformTableCreator,
FunctionName.MSSQL_DATA_ACCESS, FunctionName.MSSQL_DATA_ACCESS,
) )
GOOGLE_BIG_QUERY = ( GOOGLE_BIG_QUERY = (
GoogleBigQueryTableFullNameCreator, GoogleBigQueryDataPlatformTableCreator,
FunctionName.GOOGLE_BIGQUERY_DATA_ACCESS, FunctionName.GOOGLE_BIGQUERY_DATA_ACCESS,
) )
AMAZON_REDSHIFT = ( AMAZON_REDSHIFT = (
AmazonRedshiftFullNameCreator, AmazonRedshiftDataPlatformTableCreator,
FunctionName.AMAZON_REDSHIFT_DATA_ACCESS, FunctionName.AMAZON_REDSHIFT_DATA_ACCESS,
) )
NATIVE_QUERY = ( NATIVE_QUERY = (
NativeQueryTableFullNameCreator, NativeQueryDataPlatformTableCreator,
FunctionName.NATIVE_QUERY, FunctionName.NATIVE_QUERY,
) )
def get_table_full_name_creator(self) -> Type[AbstractTableFullNameCreator]: def get_table_full_name_creator(self) -> Type[AbstractDataPlatformTableCreator]:
return self.value[0] return self.value[0]
def get_function_name(self) -> str: def get_function_name(self) -> str:

View File

@ -120,7 +120,7 @@ def remove_whitespaces_from_list(values: List[str]) -> List[str]:
return result return result
def strip_char_from_list(values: List[str], char: str) -> List[str]: def strip_char_from_list(values: List[str], char: str = '"') -> List[str]:
result: List[str] = [] result: List[str] = []
for item in values: for item in values:
result.append(item.strip(char)) result.append(item.strip(char))

View File

@ -5,11 +5,10 @@
######################################################### #########################################################
import logging import logging
from typing import Iterable, List, Optional, Tuple, Union, cast from typing import Iterable, List, Optional, Tuple
import datahub.emitter.mce_builder as builder import datahub.emitter.mce_builder as builder
import datahub.ingestion.source.powerbi.rest_api_wrapper.data_classes as powerbi_data_classes import datahub.ingestion.source.powerbi.rest_api_wrapper.data_classes as powerbi_data_classes
from datahub.configuration.source_common import DEFAULT_ENV
from datahub.emitter.mcp import MetadataChangeProposalWrapper from datahub.emitter.mcp import MetadataChangeProposalWrapper
from datahub.emitter.mcp_builder import gen_containers from datahub.emitter.mcp_builder import gen_containers
from datahub.ingestion.api.common import PipelineContext from datahub.ingestion.api.common import PipelineContext
@ -30,6 +29,10 @@ from datahub.ingestion.source.powerbi.config import (
PowerBiDashboardSourceConfig, PowerBiDashboardSourceConfig,
PowerBiDashboardSourceReport, PowerBiDashboardSourceReport,
) )
from datahub.ingestion.source.powerbi.dataplatform_instance_resolver import (
AbstractDataPlatformInstanceResolver,
create_dataplatform_instance_resolver,
)
from datahub.ingestion.source.powerbi.m_query import parser, resolver from datahub.ingestion.source.powerbi.m_query import parser, resolver
from datahub.ingestion.source.powerbi.rest_api_wrapper.powerbi_api import PowerBiAPI from datahub.ingestion.source.powerbi.rest_api_wrapper.powerbi_api import PowerBiAPI
from datahub.ingestion.source.state.sql_common_state import ( from datahub.ingestion.source.state.sql_common_state import (
@ -95,9 +98,11 @@ class Mapper:
self, self,
config: PowerBiDashboardSourceConfig, config: PowerBiDashboardSourceConfig,
reporter: PowerBiDashboardSourceReport, reporter: PowerBiDashboardSourceReport,
dataplatform_instance_resolver: AbstractDataPlatformInstanceResolver,
): ):
self.__config = config self.__config = config
self.__reporter = reporter self.__reporter = reporter
self.__dataplatform_instance_resolver = dataplatform_instance_resolver
@staticmethod @staticmethod
def urn_to_lowercase(value: str, flag: bool) -> str: def urn_to_lowercase(value: str, flag: bool) -> str:
@ -157,7 +162,9 @@ class Mapper:
upstream_tables: List[resolver.DataPlatformTable] = parser.get_upstream_tables( upstream_tables: List[resolver.DataPlatformTable] = parser.get_upstream_tables(
table, self.__reporter, parameters=parameters table, self.__reporter, parameters=parameters
) )
logger.debug(
f"PowerBI virtual table {table.full_name} and it's upstream dataplatform tables = {upstream_tables}"
)
for upstream_table in upstream_tables: for upstream_table in upstream_tables:
if ( if (
upstream_table.data_platform_pair.powerbi_data_platform_name upstream_table.data_platform_pair.powerbi_data_platform_name
@ -168,27 +175,15 @@ class Mapper:
) )
continue continue
platform: Union[str, PlatformDetail] = self.__config.dataset_type_mapping[ platform_detail: PlatformDetail = (
upstream_table.data_platform_pair.powerbi_data_platform_name self.__dataplatform_instance_resolver.get_platform_instance(
] upstream_table
)
platform_name: str = (
upstream_table.data_platform_pair.datahub_data_platform_name
) )
platform_instance_name: Optional[str] = None
platform_env: str = DEFAULT_ENV
# Determine if PlatformDetail is provided
if isinstance(platform, PlatformDetail):
platform_instance_name = cast(
PlatformDetail, platform
).platform_instance
platform_env = cast(PlatformDetail, platform).env
upstream_urn = builder.make_dataset_urn_with_platform_instance( upstream_urn = builder.make_dataset_urn_with_platform_instance(
platform=platform_name, platform=upstream_table.data_platform_pair.datahub_data_platform_name,
platform_instance=platform_instance_name, platform_instance=platform_detail.platform_instance,
env=platform_env, env=platform_detail.env,
name=self.lineage_urn_to_lowercase(upstream_table.full_name), name=self.lineage_urn_to_lowercase(upstream_table.full_name),
) )
@ -200,9 +195,7 @@ class Mapper:
if len(upstreams) > 0: if len(upstreams) > 0:
upstream_lineage = UpstreamLineageClass(upstreams=upstreams) upstream_lineage = UpstreamLineageClass(upstreams=upstreams)
logger.debug( logger.debug(f"Dataset urn = {ds_urn} and its lineage = {upstream_lineage}")
f"DataSet Lineage = {ds_urn} and its lineage = {upstream_lineage}"
)
mcp = MetadataChangeProposalWrapper( mcp = MetadataChangeProposalWrapper(
entityType=Constant.DATASET, entityType=Constant.DATASET,
changeType=ChangeTypeClass.UPSERT, changeType=ChangeTypeClass.UPSERT,
@ -906,6 +899,7 @@ class PowerBiDashboardSource(StatefulIngestionSourceBase):
source_config: PowerBiDashboardSourceConfig source_config: PowerBiDashboardSourceConfig
reporter: PowerBiDashboardSourceReport reporter: PowerBiDashboardSourceReport
dataplatform_instance_resolver: AbstractDataPlatformInstanceResolver
accessed_dashboards: int = 0 accessed_dashboards: int = 0
platform: str = "powerbi" platform: str = "powerbi"
@ -913,15 +907,19 @@ class PowerBiDashboardSource(StatefulIngestionSourceBase):
super(PowerBiDashboardSource, self).__init__(config, ctx) super(PowerBiDashboardSource, self).__init__(config, ctx)
self.source_config = config self.source_config = config
self.reporter = PowerBiDashboardSourceReport() self.reporter = PowerBiDashboardSourceReport()
self.dataplatform_instance_resolver = create_dataplatform_instance_resolver(
self.source_config
)
try: try:
self.powerbi_client = PowerBiAPI(self.source_config) self.powerbi_client = PowerBiAPI(self.source_config)
except Exception as e: except Exception as e:
logger.warning(e) logger.warning(e)
exit( exit(
1 1
) # Exit pipeline as we are not able to connect to PowerBI API Service. This exit will avoid raising unwanted stacktrace on console ) # Exit pipeline as we are not able to connect to PowerBI API Service. This exit will avoid raising
# unwanted stacktrace on console
self.mapper = Mapper(config, self.reporter) self.mapper = Mapper(config, self.reporter, self.dataplatform_instance_resolver)
# Create and register the stateful ingestion use-case handler. # Create and register the stateful ingestion use-case handler.
self.stale_entity_removal_handler = StaleEntityRemovalHandler( self.stale_entity_removal_handler = StaleEntityRemovalHandler(
@ -962,6 +960,10 @@ class PowerBiDashboardSource(StatefulIngestionSourceBase):
if key not in powerbi_data_platforms: if key not in powerbi_data_platforms:
raise ValueError(f"PowerBI DataPlatform {key} is not supported") raise ValueError(f"PowerBI DataPlatform {key} is not supported")
logger.debug(
f"Dataset lineage would get ingested for data-platform = {self.source_config.dataset_type_mapping}"
)
def get_workunits_internal(self) -> Iterable[MetadataWorkUnit]: def get_workunits_internal(self) -> Iterable[MetadataWorkUnit]:
""" """
Datahub Ingestion framework invoke this method Datahub Ingestion framework invoke this method

View File

@ -0,0 +1,861 @@
[
{
"entityType": "dataset",
"entityUrn": "urn:li:dataset:(urn:li:dataPlatform:powerbi,library-dataset.public_issue_history,DEV)",
"changeType": "UPSERT",
"aspectName": "datasetProperties",
"aspect": {
"json": {
"customProperties": {},
"name": "public issue_history",
"description": "Library dataset description",
"tags": []
}
},
"systemMetadata": {
"lastObserved": 1643871600000,
"runId": "powerbi-test"
}
},
{
"entityType": "dataset",
"entityUrn": "urn:li:dataset:(urn:li:dataPlatform:powerbi,library-dataset.public_issue_history,DEV)",
"changeType": "UPSERT",
"aspectName": "status",
"aspect": {
"json": {
"removed": false
}
},
"systemMetadata": {
"lastObserved": 1643871600000,
"runId": "powerbi-test"
}
},
{
"entityType": "dataset",
"entityUrn": "urn:li:dataset:(urn:li:dataPlatform:powerbi,library-dataset.SNOWFLAKE_TESTTABLE,DEV)",
"changeType": "UPSERT",
"aspectName": "datasetProperties",
"aspect": {
"json": {
"customProperties": {},
"name": "SNOWFLAKE_TESTTABLE",
"description": "Library dataset description",
"tags": []
}
},
"systemMetadata": {
"lastObserved": 1643871600000,
"runId": "powerbi-test"
}
},
{
"entityType": "dataset",
"entityUrn": "urn:li:dataset:(urn:li:dataPlatform:powerbi,library-dataset.SNOWFLAKE_TESTTABLE,DEV)",
"changeType": "UPSERT",
"aspectName": "status",
"aspect": {
"json": {
"removed": false
}
},
"systemMetadata": {
"lastObserved": 1643871600000,
"runId": "powerbi-test"
}
},
{
"entityType": "dataset",
"entityUrn": "urn:li:dataset:(urn:li:dataPlatform:powerbi,library-dataset.SNOWFLAKE_TESTTABLE,DEV)",
"changeType": "UPSERT",
"aspectName": "upstreamLineage",
"aspect": {
"json": {
"upstreams": [
{
"auditStamp": {
"time": 0,
"actor": "urn:li:corpuser:unknown"
},
"dataset": "urn:li:dataset:(urn:li:dataPlatform:snowflake,snowflake_production_instance.pbi_test.test.testtable,PROD)",
"type": "TRANSFORMED"
}
]
}
},
"systemMetadata": {
"lastObserved": 1643871600000,
"runId": "powerbi-test"
}
},
{
"entityType": "dataset",
"entityUrn": "urn:li:dataset:(urn:li:dataPlatform:powerbi,library-dataset.snowflake_native-query,DEV)",
"changeType": "UPSERT",
"aspectName": "datasetProperties",
"aspect": {
"json": {
"customProperties": {},
"name": "snowflake native-query",
"description": "Library dataset description",
"tags": []
}
},
"systemMetadata": {
"lastObserved": 1643871600000,
"runId": "powerbi-test"
}
},
{
"entityType": "dataset",
"entityUrn": "urn:li:dataset:(urn:li:dataPlatform:powerbi,library-dataset.snowflake_native-query,DEV)",
"changeType": "UPSERT",
"aspectName": "status",
"aspect": {
"json": {
"removed": false
}
},
"systemMetadata": {
"lastObserved": 1643871600000,
"runId": "powerbi-test"
}
},
{
"entityType": "dataset",
"entityUrn": "urn:li:dataset:(urn:li:dataPlatform:powerbi,library-dataset.snowflake_native-query,DEV)",
"changeType": "UPSERT",
"aspectName": "upstreamLineage",
"aspect": {
"json": {
"upstreams": [
{
"auditStamp": {
"time": 0,
"actor": "urn:li:corpuser:unknown"
},
"dataset": "urn:li:dataset:(urn:li:dataPlatform:snowflake,operations_analytics.transformed_prod.v_aps_sme_units_v4,PROD)",
"type": "TRANSFORMED"
}
]
}
},
"systemMetadata": {
"lastObserved": 1643871600000,
"runId": "powerbi-test"
}
},
{
"entityType": "dataset",
"entityUrn": "urn:li:dataset:(urn:li:dataPlatform:powerbi,library-dataset.big-query-with-parameter,DEV)",
"changeType": "UPSERT",
"aspectName": "datasetProperties",
"aspect": {
"json": {
"customProperties": {},
"name": "big-query-with-parameter",
"description": "Library dataset description",
"tags": []
}
},
"systemMetadata": {
"lastObserved": 1643871600000,
"runId": "powerbi-test"
}
},
{
"entityType": "dataset",
"entityUrn": "urn:li:dataset:(urn:li:dataPlatform:powerbi,library-dataset.big-query-with-parameter,DEV)",
"changeType": "UPSERT",
"aspectName": "status",
"aspect": {
"json": {
"removed": false
}
},
"systemMetadata": {
"lastObserved": 1643871600000,
"runId": "powerbi-test"
}
},
{
"entityType": "dataset",
"entityUrn": "urn:li:dataset:(urn:li:dataPlatform:powerbi,library-dataset.big-query-with-parameter,DEV)",
"changeType": "UPSERT",
"aspectName": "upstreamLineage",
"aspect": {
"json": {
"upstreams": [
{
"auditStamp": {
"time": 0,
"actor": "urn:li:corpuser:unknown"
},
"dataset": "urn:li:dataset:(urn:li:dataPlatform:bigquery,bigquery-computing-dev-account.my-test-project.universal.d_wh_date,QA)",
"type": "TRANSFORMED"
}
]
}
},
"systemMetadata": {
"lastObserved": 1643871600000,
"runId": "powerbi-test"
}
},
{
"entityType": "dataset",
"entityUrn": "urn:li:dataset:(urn:li:dataPlatform:powerbi,library-dataset.snowflake_native-query-with-join,DEV)",
"changeType": "UPSERT",
"aspectName": "datasetProperties",
"aspect": {
"json": {
"customProperties": {},
"name": "snowflake native-query-with-join",
"description": "Library dataset description",
"tags": []
}
},
"systemMetadata": {
"lastObserved": 1643871600000,
"runId": "powerbi-test"
}
},
{
"entityType": "dataset",
"entityUrn": "urn:li:dataset:(urn:li:dataPlatform:powerbi,library-dataset.snowflake_native-query-with-join,DEV)",
"changeType": "UPSERT",
"aspectName": "status",
"aspect": {
"json": {
"removed": false
}
},
"systemMetadata": {
"lastObserved": 1643871600000,
"runId": "powerbi-test"
}
},
{
"entityType": "dataset",
"entityUrn": "urn:li:dataset:(urn:li:dataPlatform:powerbi,library-dataset.snowflake_native-query-with-join,DEV)",
"changeType": "UPSERT",
"aspectName": "upstreamLineage",
"aspect": {
"json": {
"upstreams": [
{
"auditStamp": {
"time": 0,
"actor": "urn:li:corpuser:unknown"
},
"dataset": "urn:li:dataset:(urn:li:dataPlatform:snowflake,gsl_test_db.public.sales_analyst,PROD)",
"type": "TRANSFORMED"
},
{
"auditStamp": {
"time": 0,
"actor": "urn:li:corpuser:unknown"
},
"dataset": "urn:li:dataset:(urn:li:dataPlatform:snowflake,gsl_test_db.public.sales_forecast,PROD)",
"type": "TRANSFORMED"
}
]
}
},
"systemMetadata": {
"lastObserved": 1643871600000,
"runId": "powerbi-test"
}
},
{
"entityType": "dataset",
"entityUrn": "urn:li:dataset:(urn:li:dataPlatform:powerbi,library-dataset.job-history,DEV)",
"changeType": "UPSERT",
"aspectName": "datasetProperties",
"aspect": {
"json": {
"customProperties": {},
"name": "job-history",
"description": "Library dataset description",
"tags": []
}
},
"systemMetadata": {
"lastObserved": 1643871600000,
"runId": "powerbi-test"
}
},
{
"entityType": "dataset",
"entityUrn": "urn:li:dataset:(urn:li:dataPlatform:powerbi,library-dataset.job-history,DEV)",
"changeType": "UPSERT",
"aspectName": "status",
"aspect": {
"json": {
"removed": false
}
},
"systemMetadata": {
"lastObserved": 1643871600000,
"runId": "powerbi-test"
}
},
{
"entityType": "dataset",
"entityUrn": "urn:li:dataset:(urn:li:dataPlatform:powerbi,library-dataset.job-history,DEV)",
"changeType": "UPSERT",
"aspectName": "upstreamLineage",
"aspect": {
"json": {
"upstreams": [
{
"auditStamp": {
"time": 0,
"actor": "urn:li:corpuser:unknown"
},
"dataset": "urn:li:dataset:(urn:li:dataPlatform:oracle,oracle-sales-instance.salesdb.hr.employees,PROD)",
"type": "TRANSFORMED"
}
]
}
},
"systemMetadata": {
"lastObserved": 1643871600000,
"runId": "powerbi-test"
}
},
{
"entityType": "dataset",
"entityUrn": "urn:li:dataset:(urn:li:dataPlatform:powerbi,library-dataset.postgres_test_table,DEV)",
"changeType": "UPSERT",
"aspectName": "datasetProperties",
"aspect": {
"json": {
"customProperties": {},
"name": "postgres_test_table",
"description": "Library dataset description",
"tags": []
}
},
"systemMetadata": {
"lastObserved": 1643871600000,
"runId": "powerbi-test"
}
},
{
"entityType": "dataset",
"entityUrn": "urn:li:dataset:(urn:li:dataPlatform:powerbi,library-dataset.postgres_test_table,DEV)",
"changeType": "UPSERT",
"aspectName": "status",
"aspect": {
"json": {
"removed": false
}
},
"systemMetadata": {
"lastObserved": 1643871600000,
"runId": "powerbi-test"
}
},
{
"entityType": "dataset",
"entityUrn": "urn:li:dataset:(urn:li:dataPlatform:powerbi,library-dataset.postgres_test_table,DEV)",
"changeType": "UPSERT",
"aspectName": "upstreamLineage",
"aspect": {
"json": {
"upstreams": [
{
"auditStamp": {
"time": 0,
"actor": "urn:li:corpuser:unknown"
},
"dataset": "urn:li:dataset:(urn:li:dataPlatform:postgres,mics.public.order_date,PROD)",
"type": "TRANSFORMED"
}
]
}
},
"systemMetadata": {
"lastObserved": 1643871600000,
"runId": "powerbi-test"
}
},
{
"entityType": "dataset",
"entityUrn": "urn:li:dataset:(urn:li:dataPlatform:powerbi,hr_pbi_test.dbo_book_issue,DEV)",
"changeType": "UPSERT",
"aspectName": "datasetProperties",
"aspect": {
"json": {
"customProperties": {},
"name": "dbo_book_issue",
"description": "hr pbi test description",
"tags": []
}
},
"systemMetadata": {
"lastObserved": 1643871600000,
"runId": "powerbi-test"
}
},
{
"entityType": "dataset",
"entityUrn": "urn:li:dataset:(urn:li:dataPlatform:powerbi,hr_pbi_test.dbo_book_issue,DEV)",
"changeType": "UPSERT",
"aspectName": "status",
"aspect": {
"json": {
"removed": false
}
},
"systemMetadata": {
"lastObserved": 1643871600000,
"runId": "powerbi-test"
}
},
{
"entityType": "dataset",
"entityUrn": "urn:li:dataset:(urn:li:dataPlatform:powerbi,hr_pbi_test.dbo_book_issue,DEV)",
"changeType": "UPSERT",
"aspectName": "upstreamLineage",
"aspect": {
"json": {
"upstreams": [
{
"auditStamp": {
"time": 0,
"actor": "urn:li:corpuser:unknown"
},
"dataset": "urn:li:dataset:(urn:li:dataPlatform:mssql,library.dbo.book_issue,PROD)",
"type": "TRANSFORMED"
}
]
}
},
"systemMetadata": {
"lastObserved": 1643871600000,
"runId": "powerbi-test"
}
},
{
"entityType": "dataset",
"entityUrn": "urn:li:dataset:(urn:li:dataPlatform:powerbi,hr_pbi_test.ms_sql_native_table,DEV)",
"changeType": "UPSERT",
"aspectName": "datasetProperties",
"aspect": {
"json": {
"customProperties": {},
"name": "ms_sql_native_table",
"description": "hr pbi test description",
"tags": []
}
},
"systemMetadata": {
"lastObserved": 1643871600000,
"runId": "powerbi-test"
}
},
{
"entityType": "dataset",
"entityUrn": "urn:li:dataset:(urn:li:dataPlatform:powerbi,hr_pbi_test.ms_sql_native_table,DEV)",
"changeType": "UPSERT",
"aspectName": "status",
"aspect": {
"json": {
"removed": false
}
},
"systemMetadata": {
"lastObserved": 1643871600000,
"runId": "powerbi-test"
}
},
{
"entityType": "dataset",
"entityUrn": "urn:li:dataset:(urn:li:dataPlatform:powerbi,hr_pbi_test.ms_sql_native_table,DEV)",
"changeType": "UPSERT",
"aspectName": "upstreamLineage",
"aspect": {
"json": {
"upstreams": [
{
"auditStamp": {
"time": 0,
"actor": "urn:li:corpuser:unknown"
},
"dataset": "urn:li:dataset:(urn:li:dataPlatform:mssql,commopsdb.dbo.v_ps_cd_retention,PROD)",
"type": "TRANSFORMED"
}
]
}
},
"systemMetadata": {
"lastObserved": 1643871600000,
"runId": "powerbi-test"
}
},
{
"entityType": "corpuser",
"entityUrn": "urn:li:corpuser:users.User1@foo.com",
"changeType": "UPSERT",
"aspectName": "corpUserKey",
"aspect": {
"json": {
"username": "User1@foo.com"
}
},
"systemMetadata": {
"lastObserved": 1643871600000,
"runId": "powerbi-test"
}
},
{
"entityType": "corpuser",
"entityUrn": "urn:li:corpuser:users.User2@foo.com",
"changeType": "UPSERT",
"aspectName": "corpUserKey",
"aspect": {
"json": {
"username": "User2@foo.com"
}
},
"systemMetadata": {
"lastObserved": 1643871600000,
"runId": "powerbi-test"
}
},
{
"entityType": "chart",
"entityUrn": "urn:li:chart:(powerbi,charts.B8E293DC-0C83-4AA0-9BB9-0A8738DF24A0)",
"changeType": "UPSERT",
"aspectName": "chartInfo",
"aspect": {
"json": {
"customProperties": {
"createdFrom": "Dataset",
"datasetId": "05169CD2-E713-41E6-9600-1D8066D95445",
"datasetWebUrl": "http://localhost/groups/64ED5CAD-7C10-4684-8180-826122881108/datasets/05169CD2-E713-41E6-9600-1D8066D95445/details"
},
"title": "test_tile",
"description": "test_tile",
"lastModified": {
"created": {
"time": 0,
"actor": "urn:li:corpuser:unknown"
},
"lastModified": {
"time": 0,
"actor": "urn:li:corpuser:unknown"
}
},
"inputs": [
{
"string": "urn:li:dataset:(urn:li:dataPlatform:powerbi,library-dataset.public_issue_history,DEV)"
},
{
"string": "urn:li:dataset:(urn:li:dataPlatform:powerbi,library-dataset.SNOWFLAKE_TESTTABLE,DEV)"
},
{
"string": "urn:li:dataset:(urn:li:dataPlatform:powerbi,library-dataset.snowflake_native-query,DEV)"
},
{
"string": "urn:li:dataset:(urn:li:dataPlatform:powerbi,library-dataset.big-query-with-parameter,DEV)"
},
{
"string": "urn:li:dataset:(urn:li:dataPlatform:powerbi,library-dataset.snowflake_native-query-with-join,DEV)"
},
{
"string": "urn:li:dataset:(urn:li:dataPlatform:powerbi,library-dataset.job-history,DEV)"
},
{
"string": "urn:li:dataset:(urn:li:dataPlatform:powerbi,library-dataset.postgres_test_table,DEV)"
}
]
}
},
"systemMetadata": {
"lastObserved": 1643871600000,
"runId": "powerbi-test"
}
},
{
"entityType": "chart",
"entityUrn": "urn:li:chart:(powerbi,charts.B8E293DC-0C83-4AA0-9BB9-0A8738DF24A0)",
"changeType": "UPSERT",
"aspectName": "status",
"aspect": {
"json": {
"removed": false
}
},
"systemMetadata": {
"lastObserved": 1643871600000,
"runId": "powerbi-test"
}
},
{
"entityType": "chart",
"entityUrn": "urn:li:chart:(powerbi,charts.B8E293DC-0C83-4AA0-9BB9-0A8738DF24A0)",
"changeType": "UPSERT",
"aspectName": "chartKey",
"aspect": {
"json": {
"dashboardTool": "powerbi",
"chartId": "powerbi.linkedin.com/charts/B8E293DC-0C83-4AA0-9BB9-0A8738DF24A0"
}
},
"systemMetadata": {
"lastObserved": 1643871600000,
"runId": "powerbi-test"
}
},
{
"entityType": "chart",
"entityUrn": "urn:li:chart:(powerbi,charts.B8E293DC-0C83-4AA0-9BB9-0A8738DF24A0)",
"changeType": "UPSERT",
"aspectName": "browsePaths",
"aspect": {
"json": {
"paths": [
"/powerbi/demo-workspace"
]
}
},
"systemMetadata": {
"lastObserved": 1643871600000,
"runId": "powerbi-test"
}
},
{
"entityType": "chart",
"entityUrn": "urn:li:chart:(powerbi,charts.23212598-23b5-4980-87cc-5fc0ecd84385)",
"changeType": "UPSERT",
"aspectName": "chartInfo",
"aspect": {
"json": {
"customProperties": {
"createdFrom": "Dataset",
"datasetId": "ba0130a1-5b03-40de-9535-b34e778ea6ed",
"datasetWebUrl": "http://localhost/groups/64ED5CAD-7C10-4684-8180-826122881108/datasets/ba0130a1-5b03-40de-9535-b34e778ea6ed/details"
},
"title": "yearly_sales",
"description": "yearly_sales",
"lastModified": {
"created": {
"time": 0,
"actor": "urn:li:corpuser:unknown"
},
"lastModified": {
"time": 0,
"actor": "urn:li:corpuser:unknown"
}
},
"inputs": [
{
"string": "urn:li:dataset:(urn:li:dataPlatform:powerbi,hr_pbi_test.dbo_book_issue,DEV)"
},
{
"string": "urn:li:dataset:(urn:li:dataPlatform:powerbi,hr_pbi_test.ms_sql_native_table,DEV)"
}
]
}
},
"systemMetadata": {
"lastObserved": 1643871600000,
"runId": "powerbi-test"
}
},
{
"entityType": "chart",
"entityUrn": "urn:li:chart:(powerbi,charts.23212598-23b5-4980-87cc-5fc0ecd84385)",
"changeType": "UPSERT",
"aspectName": "status",
"aspect": {
"json": {
"removed": false
}
},
"systemMetadata": {
"lastObserved": 1643871600000,
"runId": "powerbi-test"
}
},
{
"entityType": "chart",
"entityUrn": "urn:li:chart:(powerbi,charts.23212598-23b5-4980-87cc-5fc0ecd84385)",
"changeType": "UPSERT",
"aspectName": "chartKey",
"aspect": {
"json": {
"dashboardTool": "powerbi",
"chartId": "powerbi.linkedin.com/charts/23212598-23b5-4980-87cc-5fc0ecd84385"
}
},
"systemMetadata": {
"lastObserved": 1643871600000,
"runId": "powerbi-test"
}
},
{
"entityType": "chart",
"entityUrn": "urn:li:chart:(powerbi,charts.23212598-23b5-4980-87cc-5fc0ecd84385)",
"changeType": "UPSERT",
"aspectName": "browsePaths",
"aspect": {
"json": {
"paths": [
"/powerbi/demo-workspace"
]
}
},
"systemMetadata": {
"lastObserved": 1643871600000,
"runId": "powerbi-test"
}
},
{
"entityType": "dashboard",
"entityUrn": "urn:li:dashboard:(powerbi,dashboards.7D668CAD-7FFC-4505-9215-655BCA5BEBAE)",
"changeType": "UPSERT",
"aspectName": "browsePaths",
"aspect": {
"json": {
"paths": [
"/powerbi/demo-workspace"
]
}
},
"systemMetadata": {
"lastObserved": 1643871600000,
"runId": "powerbi-test"
}
},
{
"entityType": "dashboard",
"entityUrn": "urn:li:dashboard:(powerbi,dashboards.7D668CAD-7FFC-4505-9215-655BCA5BEBAE)",
"changeType": "UPSERT",
"aspectName": "dashboardInfo",
"aspect": {
"json": {
"customProperties": {
"chartCount": "2",
"workspaceName": "demo-workspace",
"workspaceId": "64ED5CAD-7C10-4684-8180-826122881108"
},
"title": "test_dashboard",
"description": "Description of test dashboard",
"charts": [
"urn:li:chart:(powerbi,charts.B8E293DC-0C83-4AA0-9BB9-0A8738DF24A0)",
"urn:li:chart:(powerbi,charts.23212598-23b5-4980-87cc-5fc0ecd84385)"
],
"datasets": [],
"lastModified": {
"created": {
"time": 0,
"actor": "urn:li:corpuser:unknown"
},
"lastModified": {
"time": 0,
"actor": "urn:li:corpuser:unknown"
}
},
"dashboardUrl": "https://localhost/dashboards/web/1"
}
},
"systemMetadata": {
"lastObserved": 1643871600000,
"runId": "powerbi-test"
}
},
{
"entityType": "dashboard",
"entityUrn": "urn:li:dashboard:(powerbi,dashboards.7D668CAD-7FFC-4505-9215-655BCA5BEBAE)",
"changeType": "UPSERT",
"aspectName": "status",
"aspect": {
"json": {
"removed": false
}
},
"systemMetadata": {
"lastObserved": 1643871600000,
"runId": "powerbi-test"
}
},
{
"entityType": "dashboard",
"entityUrn": "urn:li:dashboard:(powerbi,dashboards.7D668CAD-7FFC-4505-9215-655BCA5BEBAE)",
"changeType": "UPSERT",
"aspectName": "dashboardKey",
"aspect": {
"json": {
"dashboardTool": "powerbi",
"dashboardId": "powerbi.linkedin.com/dashboards/7D668CAD-7FFC-4505-9215-655BCA5BEBAE"
}
},
"systemMetadata": {
"lastObserved": 1643871600000,
"runId": "powerbi-test"
}
},
{
"entityType": "dashboard",
"entityUrn": "urn:li:dashboard:(powerbi,dashboards.7D668CAD-7FFC-4505-9215-655BCA5BEBAE)",
"changeType": "UPSERT",
"aspectName": "ownership",
"aspect": {
"json": {
"owners": [
{
"owner": "urn:li:corpuser:users.User1@foo.com",
"type": "NONE"
},
{
"owner": "urn:li:corpuser:users.User2@foo.com",
"type": "NONE"
}
],
"lastModified": {
"time": 0,
"actor": "urn:li:corpuser:unknown"
}
}
},
"systemMetadata": {
"lastObserved": 1643871600000,
"runId": "powerbi-test"
}
},
{
"entityType": "corpuser",
"entityUrn": "urn:li:corpuser:users.User1@foo.com",
"changeType": "UPSERT",
"aspectName": "status",
"aspect": {
"json": {
"removed": false
}
},
"systemMetadata": {
"lastObserved": 1643871600000,
"runId": "powerbi-test"
}
},
{
"entityType": "corpuser",
"entityUrn": "urn:li:corpuser:users.User2@foo.com",
"changeType": "UPSERT",
"aspectName": "status",
"aspect": {
"json": {
"removed": false
}
},
"systemMetadata": {
"lastObserved": 1643871600000,
"runId": "powerbi-test"
}
}
]

View File

@ -14,23 +14,23 @@ from datahub.ingestion.source.powerbi.m_query.resolver import (
) )
M_QUERIES = [ M_QUERIES = [
'let\n Source = Snowflake.Databases("bu20658.ap-southeast-2.snowflakecomputing.com","PBI_TEST_WAREHOUSE_PROD",[Role="PBI_TEST_MEMBER"]),\n PBI_TEST_Database = Source{[Name="PBI_TEST",Kind="Database"]}[Data],\n TEST_Schema = PBI_TEST_Database{[Name="TEST",Kind="Schema"]}[Data],\n TESTTABLE_Table = TEST_Schema{[Name="TESTTABLE",Kind="Table"]}[Data]\nin\n TESTTABLE_Table', 'let\n Source = Snowflake.Databases("bu10758.ap-unknown-2.fakecomputing.com","PBI_TEST_WAREHOUSE_PROD",[Role="PBI_TEST_MEMBER"]),\n PBI_TEST_Database = Source{[Name="PBI_TEST",Kind="Database"]}[Data],\n TEST_Schema = PBI_TEST_Database{[Name="TEST",Kind="Schema"]}[Data],\n TESTTABLE_Table = TEST_Schema{[Name="TESTTABLE",Kind="Table"]}[Data]\nin\n TESTTABLE_Table',
'let\n Source = Value.NativeQuery(Snowflake.Databases("bu20658.ap-southeast-2.snowflakecomputing.com","operations_analytics_warehouse_prod",[Role="OPERATIONS_ANALYTICS_MEMBER"]){[Name="OPERATIONS_ANALYTICS"]}[Data], "SELECT#(lf)concat((UPPER(REPLACE(SELLER,\'-\',\'\'))), MONTHID) as AGENT_KEY,#(lf)concat((UPPER(REPLACE(CLIENT_DIRECTOR,\'-\',\'\'))), MONTHID) as CD_AGENT_KEY,#(lf) *#(lf)FROM#(lf)OPERATIONS_ANALYTICS.TRANSFORMED_PROD.V_APS_SME_UNITS_V4", null, [EnableFolding=true]),\n #"ADDed Conditional Column" = Table.AddColumn(Source, "SME Units ENT", each if [DEAL_TYPE] = "SME Unit" then [UNIT] else 0),\n #"Added Conditional Column1" = Table.AddColumn(#"Added Conditional Column", "Banklink Units", each if [DEAL_TYPE] = "Banklink" then [UNIT] else 0),\n #"Removed Columns" = Table.RemoveColumns(#"Added Conditional Column1",{"Banklink Units"}),\n #"Added Custom" = Table.AddColumn(#"Removed Columns", "Banklink Units", each if [DEAL_TYPE] = "Banklink" and [SALES_TYPE] = "3 - Upsell"\nthen [UNIT]\n\nelse if [SALES_TYPE] = "Adjusted BL Migration"\nthen [UNIT]\n\nelse 0),\n #"Added Custom1" = Table.AddColumn(#"Added Custom", "SME Units in $ (*$361)", each if [DEAL_TYPE] = "SME Unit" \nand [SALES_TYPE] <> "4 - Renewal"\n then [UNIT] * 361\nelse 0),\n #"Added Custom2" = Table.AddColumn(#"Added Custom1", "Banklink in $ (*$148)", each [Banklink Units] * 148)\nin\n #"Added Custom2"', 'let\n Source = Value.NativeQuery(Snowflake.Databases("bu10758.ap-unknown-2.fakecomputing.com","operations_analytics_warehouse_prod",[Role="OPERATIONS_ANALYTICS_MEMBER"]){[Name="OPERATIONS_ANALYTICS"]}[Data], "SELECT#(lf)concat((UPPER(REPLACE(SELLER,\'-\',\'\'))), MONTHID) as AGENT_KEY,#(lf)concat((UPPER(REPLACE(CLIENT_DIRECTOR,\'-\',\'\'))), MONTHID) as CD_AGENT_KEY,#(lf) *#(lf)FROM#(lf)OPERATIONS_ANALYTICS.TRANSFORMED_PROD.V_APS_SME_UNITS_V4", null, [EnableFolding=true]),\n #"ADDed Conditional Column" = Table.AddColumn(Source, "SME Units ENT", each if [DEAL_TYPE] = "SME Unit" then [UNIT] else 0),\n #"Added Conditional Column1" = Table.AddColumn(#"Added Conditional Column", "Banklink Units", each if [DEAL_TYPE] = "Banklink" then [UNIT] else 0),\n #"Removed Columns" = Table.RemoveColumns(#"Added Conditional Column1",{"Banklink Units"}),\n #"Added Custom" = Table.AddColumn(#"Removed Columns", "Banklink Units", each if [DEAL_TYPE] = "Banklink" and [SALES_TYPE] = "3 - Upsell"\nthen [UNIT]\n\nelse if [SALES_TYPE] = "Adjusted BL Migration"\nthen [UNIT]\n\nelse 0),\n #"Added Custom1" = Table.AddColumn(#"Added Custom", "SME Units in $ (*$361)", each if [DEAL_TYPE] = "SME Unit" \nand [SALES_TYPE] <> "4 - Renewal"\n then [UNIT] * 361\nelse 0),\n #"Added Custom2" = Table.AddColumn(#"Added Custom1", "Banklink in $ (*$148)", each [Banklink Units] * 148)\nin\n #"Added Custom2"',
'let\n Source = Value.NativeQuery(Snowflake.Databases("bu20 658.ap-southeast-2.snowflakecomputing.com","operations_analytics_warehouse_prod",[Role="OPERATIONS_ANALYTICS_MEMBER"]){[Name="OPERATIONS_ANALYTICS"]}[Data], "select #(lf)UPPER(REPLACE(AGENT_NAME,\'-\',\'\')) AS Agent,#(lf)TIER,#(lf)UPPER(MANAGER),#(lf)TEAM_TYPE,#(lf)DATE_TARGET,#(lf)MONTHID,#(lf)TARGET_TEAM,#(lf)SELLER_EMAIL,#(lf)concat((UPPER(REPLACE(AGENT_NAME,\'-\',\'\'))), MONTHID) as AGENT_KEY,#(lf)UNIT_TARGET AS SME_Quota,#(lf)AMV_TARGET AS Revenue_Quota,#(lf)SERVICE_QUOTA,#(lf)BL_TARGET,#(lf)SOFTWARE_QUOTA as Software_Quota#(lf)#(lf)from OPERATIONS_ANALYTICS.TRANSFORMED_PROD.V_SME_UNIT_TARGETS#(lf)#(lf)where YEAR_TARGET >= 2022#(lf)and TEAM_TYPE = \'Accounting\'#(lf)and TARGET_TEAM = \'Enterprise\'", null, [EnableFolding=true]),\n #"Added Conditional Column" = Table.AddColumn(Source, "Has PS Software Quota?", each if [TIER] = "Expansion (Medium)" then "Yes" else if [TIER] = "Acquisition" then "Yes" else "No")\nin\n #"Added Conditional Column"', 'let\n Source = Value.NativeQuery(Snowflake.Databases("bu10758.ap-unknown-2.fakecomputing.com","operations_analytics_warehouse_prod",[Role="OPERATIONS_ANALYTICS_MEMBER"]){[Name="OPERATIONS_ANALYTICS"]}[Data], "select #(lf)UPPER(REPLACE(AGENT_NAME,\'-\',\'\')) AS Agent,#(lf)TIER,#(lf)UPPER(MANAGER),#(lf)TEAM_TYPE,#(lf)DATE_TARGET,#(lf)MONTHID,#(lf)TARGET_TEAM,#(lf)SELLER_EMAIL,#(lf)concat((UPPER(REPLACE(AGENT_NAME,\'-\',\'\'))), MONTHID) as AGENT_KEY,#(lf)UNIT_TARGET AS SME_Quota,#(lf)AMV_TARGET AS Revenue_Quota,#(lf)SERVICE_QUOTA,#(lf)BL_TARGET,#(lf)SOFTWARE_QUOTA as Software_Quota#(lf)#(lf)from OPERATIONS_ANALYTICS.TRANSFORMED_PROD.V_SME_UNIT_TARGETS#(lf)#(lf)where YEAR_TARGET >= 2022#(lf)and TEAM_TYPE = \'Accounting\'#(lf)and TARGET_TEAM = \'Enterprise\'", null, [EnableFolding=true]),\n #"Added Conditional Column" = Table.AddColumn(Source, "Has PS Software Quota?", each if [TIER] = "Expansion (Medium)" then "Yes" else if [TIER] = "Acquisition" then "Yes" else "No")\nin\n #"Added Conditional Column"',
'let\n Source = Sql.Database("AUPRDWHDB", "COMMOPSDB", [Query="select *#(lf),concat((UPPER(REPLACE(CLIENT_MANAGER_QUOTED,\'-\',\'\'))), MONTHID) as AGENT_KEY#(lf),concat((UPPER(REPLACE(CLIENT_DIRECTOR,\'-\',\'\'))), MONTHID) as CD_AGENT_KEY#(lf)#(lf)from V_OIP_ENT_2022"]),\n #"Added Custom" = Table.AddColumn(Source, "OIP in $(*$350)", each [SALES_INVOICE_AMOUNT] * 350),\n #"Changed Type" = Table.TransformColumnTypes(#"Added Custom",{{"OIP in $(*$350)", type number}})\nin\n #"Changed Type"', 'let\n Source = Sql.Database("AUPRDWHDB", "COMMOPSDB", [Query="select *#(lf),concat((UPPER(REPLACE(CLIENT_MANAGER_QUOTED,\'-\',\'\'))), MONTHID) as AGENT_KEY#(lf),concat((UPPER(REPLACE(CLIENT_DIRECTOR,\'-\',\'\'))), MONTHID) as CD_AGENT_KEY#(lf)#(lf)from V_OIP_ENT_2022"]),\n #"Added Custom" = Table.AddColumn(Source, "OIP in $(*$350)", each [SALES_INVOICE_AMOUNT] * 350),\n #"Changed Type" = Table.TransformColumnTypes(#"Added Custom",{{"OIP in $(*$350)", type number}})\nin\n #"Changed Type"',
'let\n Source = Sql.Database("AUPRDWHDB", "COMMOPSDB", [Query="Select *,#(lf)#(lf)concat((UPPER(REPLACE(CLIENT_MANAGER_QUOTED,\'-\',\'\'))), #(lf)LEFT(CAST(DTE AS DATE),4)+LEFT(RIGHT(CAST(DTE AS DATE),5),2)) AS AGENT_KEY,#(lf)concat((UPPER(REPLACE(CLIENT_DIRECTOR,\'-\',\'\'))), #(lf)LEFT(CAST(DTE AS DATE),4)+LEFT(RIGHT(CAST(DTE AS DATE),5),2)) AS CD_AGENT_KEY#(lf)#(lf)from V_INVOICE_BOOKING_2022"]),\n #"Changed Type" = Table.TransformColumnTypes(Source,{{"CLIENT_ID", Int64.Type}}),\n #"Added Conditional Column" = Table.AddColumn(#"Changed Type", "PS Software (One-Off)", each if Text.Contains([REVENUE_TYPE], "Software") then [Inv_Amt] else if Text.Contains([REVENUE_TYPE], "Tax Seminar") then [Inv_Amt] else 0),\n #"Filtered Rows" = Table.SelectRows(#"Added Conditional Column", each true),\n #"Duplicated Column" = Table.DuplicateColumn(#"Filtered Rows", "CLIENT_ID", "CLIENT_ID - Copy"),\n #"Changed Type1" = Table.TransformColumnTypes(#"Duplicated Column",{{"CLIENT_ID - Copy", type text}}),\n #"Renamed Columns" = Table.RenameColumns(#"Changed Type1",{{"CLIENT_ID - Copy", "CLIENT_ID for Filter"}})\nin\n #"Renamed Columns"', 'let\n Source = Sql.Database("AUPRDWHDB", "COMMOPSDB", [Query="Select *,#(lf)#(lf)concat((UPPER(REPLACE(CLIENT_MANAGER_QUOTED,\'-\',\'\'))), #(lf)LEFT(CAST(DTE AS DATE),4)+LEFT(RIGHT(CAST(DTE AS DATE),5),2)) AS AGENT_KEY,#(lf)concat((UPPER(REPLACE(CLIENT_DIRECTOR,\'-\',\'\'))), #(lf)LEFT(CAST(DTE AS DATE),4)+LEFT(RIGHT(CAST(DTE AS DATE),5),2)) AS CD_AGENT_KEY#(lf)#(lf)from V_INVOICE_BOOKING_2022"]),\n #"Changed Type" = Table.TransformColumnTypes(Source,{{"CLIENT_ID", Int64.Type}}),\n #"Added Conditional Column" = Table.AddColumn(#"Changed Type", "PS Software (One-Off)", each if Text.Contains([REVENUE_TYPE], "Software") then [Inv_Amt] else if Text.Contains([REVENUE_TYPE], "Tax Seminar") then [Inv_Amt] else 0),\n #"Filtered Rows" = Table.SelectRows(#"Added Conditional Column", each true),\n #"Duplicated Column" = Table.DuplicateColumn(#"Filtered Rows", "CLIENT_ID", "CLIENT_ID - Copy"),\n #"Changed Type1" = Table.TransformColumnTypes(#"Duplicated Column",{{"CLIENT_ID - Copy", type text}}),\n #"Renamed Columns" = Table.RenameColumns(#"Changed Type1",{{"CLIENT_ID - Copy", "CLIENT_ID for Filter"}})\nin\n #"Renamed Columns"',
'let\n Source = Sql.Database("AUPRDWHDB", "COMMOPSDB", [Query="SELECT *,#(lf)concat((UPPER(REPLACE(CLIENT_MANAGER_CLOSING_MONTH,\'-\',\'\'))), #(lf)LEFT(CAST(MONTH_DATE AS DATE),4)+LEFT(RIGHT(CAST(MONTH_DATE AS DATE),5),2)) AS AGENT_KEY#(lf)#(lf)FROM dbo.V_ARR_ADDS"]),\n #"Changed Type" = Table.TransformColumnTypes(Source,{{"MONTH_DATE", type date}}),\n #"Added Custom" = Table.AddColumn(#"Changed Type", "Month", each Date.Month([MONTH_DATE]))\nin\n #"Added Custom"', 'let\n Source = Sql.Database("AUPRDWHDB", "COMMOPSDB", [Query="SELECT *,#(lf)concat((UPPER(REPLACE(CLIENT_MANAGER_CLOSING_MONTH,\'-\',\'\'))), #(lf)LEFT(CAST(MONTH_DATE AS DATE),4)+LEFT(RIGHT(CAST(MONTH_DATE AS DATE),5),2)) AS AGENT_KEY#(lf)#(lf)FROM dbo.V_ARR_ADDS"]),\n #"Changed Type" = Table.TransformColumnTypes(Source,{{"MONTH_DATE", type date}}),\n #"Added Custom" = Table.AddColumn(#"Changed Type", "Month", each Date.Month([MONTH_DATE]))\nin\n #"Added Custom"',
"let\n Source = Value.NativeQuery(Snowflake.Databases(\"bu20658.ap-southeast-2.snowflakecomputing.com\",\"operations_analytics_warehouse_prod\",[Role=\"OPERATIONS_ANALYTICS_MEMBER\"]){[Name=\"OPERATIONS_ANALYTICS\"]}[Data], \"select #(lf)UPPER(REPLACE(AGENT_NAME,'-','')) AS CLIENT_DIRECTOR,#(lf)TIER,#(lf)UPPER(MANAGER),#(lf)TEAM_TYPE,#(lf)DATE_TARGET,#(lf)MONTHID,#(lf)TARGET_TEAM,#(lf)SELLER_EMAIL,#(lf)concat((UPPER(REPLACE(AGENT_NAME,'-',''))), MONTHID) as AGENT_KEY,#(lf)UNIT_TARGET AS SME_Quota,#(lf)AMV_TARGET AS Revenue_Quota,#(lf)SERVICE_QUOTA,#(lf)BL_TARGET,#(lf)SOFTWARE_QUOTA as Software_Quota#(lf)#(lf)from OPERATIONS_ANALYTICS.TRANSFORMED_PROD.V_SME_UNIT_TARGETS#(lf)#(lf)where YEAR_TARGET >= 2022#(lf)and TEAM_TYPE = 'Accounting'#(lf)and TARGET_TEAM = 'Enterprise'#(lf)AND TIER = 'Client Director'\", null, [EnableFolding=true])\nin\n Source", "let\n Source = Value.NativeQuery(Snowflake.Databases(\"bu10758.ap-unknown-2.fakecomputing.com\",\"operations_analytics_warehouse_prod\",[Role=\"OPERATIONS_ANALYTICS_MEMBER\"]){[Name=\"OPERATIONS_ANALYTICS\"]}[Data], \"select #(lf)UPPER(REPLACE(AGENT_NAME,'-','')) AS CLIENT_DIRECTOR,#(lf)TIER,#(lf)UPPER(MANAGER),#(lf)TEAM_TYPE,#(lf)DATE_TARGET,#(lf)MONTHID,#(lf)TARGET_TEAM,#(lf)SELLER_EMAIL,#(lf)concat((UPPER(REPLACE(AGENT_NAME,'-',''))), MONTHID) as AGENT_KEY,#(lf)UNIT_TARGET AS SME_Quota,#(lf)AMV_TARGET AS Revenue_Quota,#(lf)SERVICE_QUOTA,#(lf)BL_TARGET,#(lf)SOFTWARE_QUOTA as Software_Quota#(lf)#(lf)from OPERATIONS_ANALYTICS.TRANSFORMED_PROD.V_SME_UNIT_TARGETS#(lf)#(lf)where YEAR_TARGET >= 2022#(lf)and TEAM_TYPE = 'Accounting'#(lf)and TARGET_TEAM = 'Enterprise'#(lf)AND TIER = 'Client Director'\", null, [EnableFolding=true])\nin\n Source",
'let\n Source = Sql.Database("AUPRDWHDB", "COMMOPSDB", [Query="select *,#(lf)concat((UPPER(REPLACE(CLIENT_DIRECTOR,\'-\',\'\'))), MONTH_WID) as CD_AGENT_KEY,#(lf)concat((UPPER(REPLACE(CLIENT_MANAGER_CLOSING_MONTH,\'-\',\'\'))), MONTH_WID) as AGENT_KEY#(lf)#(lf)from V_PS_CD_RETENTION", CommandTimeout=#duration(0, 1, 30, 0)]),\n #"Changed Type" = Table.TransformColumnTypes(Source,{{"mth_date", type date}}),\n #"Added Custom" = Table.AddColumn(#"Changed Type", "Month", each Date.Month([mth_date])),\n #"Added Custom1" = Table.AddColumn(#"Added Custom", "TPV Opening", each if [Month] = 1 then [TPV_AMV_OPENING]\nelse if [Month] = 2 then 0\nelse if [Month] = 3 then 0\nelse if [Month] = 4 then [TPV_AMV_OPENING]\nelse if [Month] = 5 then 0\nelse if [Month] = 6 then 0\nelse if [Month] = 7 then [TPV_AMV_OPENING]\nelse if [Month] = 8 then 0\nelse if [Month] = 9 then 0\nelse if [Month] = 10 then [TPV_AMV_OPENING]\nelse if [Month] = 11 then 0\nelse if [Month] = 12 then 0\n\nelse 0)\nin\n #"Added Custom1"', 'let\n Source = Sql.Database("AUPRDWHDB", "COMMOPSDB", [Query="select *,#(lf)concat((UPPER(REPLACE(CLIENT_DIRECTOR,\'-\',\'\'))), MONTH_WID) as CD_AGENT_KEY,#(lf)concat((UPPER(REPLACE(CLIENT_MANAGER_CLOSING_MONTH,\'-\',\'\'))), MONTH_WID) as AGENT_KEY#(lf)#(lf)from V_PS_CD_RETENTION", CommandTimeout=#duration(0, 1, 30, 0)]),\n #"Changed Type" = Table.TransformColumnTypes(Source,{{"mth_date", type date}}),\n #"Added Custom" = Table.AddColumn(#"Changed Type", "Month", each Date.Month([mth_date])),\n #"Added Custom1" = Table.AddColumn(#"Added Custom", "TPV Opening", each if [Month] = 1 then [TPV_AMV_OPENING]\nelse if [Month] = 2 then 0\nelse if [Month] = 3 then 0\nelse if [Month] = 4 then [TPV_AMV_OPENING]\nelse if [Month] = 5 then 0\nelse if [Month] = 6 then 0\nelse if [Month] = 7 then [TPV_AMV_OPENING]\nelse if [Month] = 8 then 0\nelse if [Month] = 9 then 0\nelse if [Month] = 10 then [TPV_AMV_OPENING]\nelse if [Month] = 11 then 0\nelse if [Month] = 12 then 0\n\nelse 0)\nin\n #"Added Custom1"',
'let\n Source = Sql.Database("AUPRDWHDB", "COMMOPSDB", [Query="select#(lf)CLIENT_ID,#(lf)PARTNER_ACCOUNT_NAME,#(lf)CM_CLOSING_MNTH_COUNTRY,#(lf)MONTH_WID,#(lf)PS_DELETES,#(lf)CLIENT_MANAGER_CLOSING_MONTH,#(lf)SME_DELETES,#(lf)TPV_AMV_OPENING,#(lf)concat((UPPER(REPLACE(CLIENT_MANAGER_CLOSING_MONTH,\'-\',\'\'))), MONTH_WID) as AGENT_KEY#(lf)#(lf)from V_TPV_LEADERBOARD", CommandTimeout=#duration(0, 1, 30, 0)]),\n #"Changed Type" = Table.TransformColumnTypes(Source,{{"MONTH_WID", type text}}),\n #"Added Custom" = Table.AddColumn(#"Changed Type", "MONTH_DATE", each Date.FromText(\nText.Range([MONTH_WID], 0,4) & "-" &\nText.Range([MONTH_WID], 4,2)\n)),\n #"Added Custom2" = Table.AddColumn(#"Added Custom", "Month", each Date.Month([MONTH_DATE])),\n #"Added Custom1" = Table.AddColumn(#"Added Custom2", "TPV Opening", each if [Month] = 1 then [TPV_AMV_OPENING]\nelse if [Month] = 2 then 0\nelse if [Month] = 3 then 0\nelse if [Month] = 4 then [TPV_AMV_OPENING]\nelse if [Month] = 5 then 0\nelse if [Month] = 6 then 0\nelse if [Month] = 7 then [TPV_AMV_OPENING]\nelse if [Month] = 8 then 0\nelse if [Month] = 9 then 0\nelse if [Month] = 10 then [TPV_AMV_OPENING]\nelse if [Month] = 11 then 0\nelse if [Month] = 12 then 0\n\nelse 0)\nin\n #"Added Custom1"', 'let\n Source = Sql.Database("AUPRDWHDB", "COMMOPSDB", [Query="select#(lf)CLIENT_ID,#(lf)PARTNER_ACCOUNT_NAME,#(lf)CM_CLOSING_MNTH_COUNTRY,#(lf)MONTH_WID,#(lf)PS_DELETES,#(lf)CLIENT_MANAGER_CLOSING_MONTH,#(lf)SME_DELETES,#(lf)TPV_AMV_OPENING,#(lf)concat((UPPER(REPLACE(CLIENT_MANAGER_CLOSING_MONTH,\'-\',\'\'))), MONTH_WID) as AGENT_KEY#(lf)#(lf)from V_TPV_LEADERBOARD", CommandTimeout=#duration(0, 1, 30, 0)]),\n #"Changed Type" = Table.TransformColumnTypes(Source,{{"MONTH_WID", type text}}),\n #"Added Custom" = Table.AddColumn(#"Changed Type", "MONTH_DATE", each Date.FromText(\nText.Range([MONTH_WID], 0,4) & "-" &\nText.Range([MONTH_WID], 4,2)\n)),\n #"Added Custom2" = Table.AddColumn(#"Added Custom", "Month", each Date.Month([MONTH_DATE])),\n #"Added Custom1" = Table.AddColumn(#"Added Custom2", "TPV Opening", each if [Month] = 1 then [TPV_AMV_OPENING]\nelse if [Month] = 2 then 0\nelse if [Month] = 3 then 0\nelse if [Month] = 4 then [TPV_AMV_OPENING]\nelse if [Month] = 5 then 0\nelse if [Month] = 6 then 0\nelse if [Month] = 7 then [TPV_AMV_OPENING]\nelse if [Month] = 8 then 0\nelse if [Month] = 9 then 0\nelse if [Month] = 10 then [TPV_AMV_OPENING]\nelse if [Month] = 11 then 0\nelse if [Month] = 12 then 0\n\nelse 0)\nin\n #"Added Custom1"',
'let\n Source = Snowflake.Databases("bu20658.ap-southeast-2.snowflakecomputing.com","OPERATIONS_ANALYTICS_WAREHOUSE_PROD",[Role="OPERATIONS_ANALYTICS_MEMBER_AD"]),\n OPERATIONS_ANALYTICS_Database = Source{[Name="OPERATIONS_ANALYTICS",Kind="Database"]}[Data],\n TEST_Schema = OPERATIONS_ANALYTICS_Database{[Name="TEST",Kind="Schema"]}[Data],\n LZ_MIGRATION_DOWNLOAD_View = TEST_Schema{[Name="LZ_MIGRATION_DOWNLOAD",Kind="View"]}[Data],\n #"Changed Type" = Table.TransformColumnTypes(LZ_MIGRATION_DOWNLOAD_View,{{"MIGRATION_MONTH_ID", type text}}),\n #"Added Custom" = Table.AddColumn(#"Changed Type", "Migration Month", each Date.FromText(\nText.Range([MIGRATION_MONTH_ID], 0,4) & "-" & \nText.Range([MIGRATION_MONTH_ID], 4,2) \n)),\n #"Changed Type1" = Table.TransformColumnTypes(#"Added Custom",{{"Migration Month", type date}})\nin\n #"Changed Type1"', 'let\n Source = Snowflake.Databases("bu10758.ap-unknown-2.fakecomputing.com","OPERATIONS_ANALYTICS_WAREHOUSE_PROD",[Role="OPERATIONS_ANALYTICS_MEMBER_AD"]),\n OPERATIONS_ANALYTICS_Database = Source{[Name="OPERATIONS_ANALYTICS",Kind="Database"]}[Data],\n TEST_Schema = OPERATIONS_ANALYTICS_Database{[Name="TEST",Kind="Schema"]}[Data],\n LZ_MIGRATION_DOWNLOAD_View = TEST_Schema{[Name="LZ_MIGRATION_DOWNLOAD",Kind="View"]}[Data],\n #"Changed Type" = Table.TransformColumnTypes(LZ_MIGRATION_DOWNLOAD_View,{{"MIGRATION_MONTH_ID", type text}}),\n #"Added Custom" = Table.AddColumn(#"Changed Type", "Migration Month", each Date.FromText(\nText.Range([MIGRATION_MONTH_ID], 0,4) & "-" & \nText.Range([MIGRATION_MONTH_ID], 4,2) \n)),\n #"Changed Type1" = Table.TransformColumnTypes(#"Added Custom",{{"Migration Month", type date}})\nin\n #"Changed Type1"',
"let\n Source = Value.NativeQuery(Snowflake.Databases(\"bu20658.ap-southeast-2.snowflakecomputing.com\",\"operations_analytics_warehouse_prod\",[Role=\"OPERATIONS_ANALYTICS_MEMBER\"]){[Name=\"OPERATIONS_ANALYTICS\"]}[Data], \"select *,#(lf)UPPER(REPLACE(AGENT_NAME,'-','')) AS Agent,#(lf)concat((UPPER(REPLACE(AGENT_NAME,'-',''))), MONTHID) as AGENT_KEY#(lf)#(lf)from OPERATIONS_ANALYTICS.TRANSFORMED_PROD.V_SME_UNIT_TARGETS#(lf)#(lf)where YEAR_TARGET >= 2022#(lf)and TEAM_TYPE = 'Industries'#(lf)and TARGET_TEAM = 'Enterprise'\", null, [EnableFolding=true])\nin\n Source", "let\n Source = Value.NativeQuery(Snowflake.Databases(\"bu10758.ap-unknown-2.fakecomputing.com\",\"operations_analytics_warehouse_prod\",[Role=\"OPERATIONS_ANALYTICS_MEMBER\"]){[Name=\"OPERATIONS_ANALYTICS\"]}[Data], \"select *,#(lf)UPPER(REPLACE(AGENT_NAME,'-','')) AS Agent,#(lf)concat((UPPER(REPLACE(AGENT_NAME,'-',''))), MONTHID) as AGENT_KEY#(lf)#(lf)from OPERATIONS_ANALYTICS.TRANSFORMED_PROD.V_SME_UNIT_TARGETS#(lf)#(lf)where YEAR_TARGET >= 2022#(lf)and TEAM_TYPE = 'Industries'#(lf)and TARGET_TEAM = 'Enterprise'\", null, [EnableFolding=true])\nin\n Source",
'let\n Source = Sql.Database("AUPRDWHDB", "COMMOPSDB", [Query="Select#(lf)*,#(lf)concat((UPPER(REPLACE(SALES_SPECIALIST,\'-\',\'\'))),#(lf)LEFT(CAST(INVOICE_DATE AS DATE),4)+LEFT(RIGHT(CAST(INVOICE_DATE AS DATE),5),2)) AS AGENT_KEY,#(lf)CASE#(lf) WHEN CLASS = \'Software\' and (NOT(PRODUCT in (\'ADV\', \'Adv\') and left(ACCOUNT_ID,2)=\'10\') #(lf) or V_ENTERPRISE_INVOICED_REVENUE.TYPE = \'Manual Adjustment\') THEN INVOICE_AMOUNT#(lf) WHEN V_ENTERPRISE_INVOICED_REVENUE.TYPE IN (\'Recurring\',\'0\') THEN INVOICE_AMOUNT#(lf) ELSE 0#(lf)END as SOFTWARE_INV#(lf)#(lf)from V_ENTERPRISE_INVOICED_REVENUE", CommandTimeout=#duration(0, 1, 30, 0)]),\n #"Added Conditional Column" = Table.AddColumn(Source, "Services", each if [CLASS] = "Services" then [INVOICE_AMOUNT] else 0),\n #"Added Custom" = Table.AddColumn(#"Added Conditional Column", "Advanced New Sites", each if [PRODUCT] = "ADV"\nor [PRODUCT] = "Adv"\nthen [NEW_SITE]\nelse 0)\nin\n #"Added Custom"', 'let\n Source = Sql.Database("AUPRDWHDB", "COMMOPSDB", [Query="Select#(lf)*,#(lf)concat((UPPER(REPLACE(SALES_SPECIALIST,\'-\',\'\'))),#(lf)LEFT(CAST(INVOICE_DATE AS DATE),4)+LEFT(RIGHT(CAST(INVOICE_DATE AS DATE),5),2)) AS AGENT_KEY,#(lf)CASE#(lf) WHEN CLASS = \'Software\' and (NOT(PRODUCT in (\'ADV\', \'Adv\') and left(ACCOUNT_ID,2)=\'10\') #(lf) or V_ENTERPRISE_INVOICED_REVENUE.TYPE = \'Manual Adjustment\') THEN INVOICE_AMOUNT#(lf) WHEN V_ENTERPRISE_INVOICED_REVENUE.TYPE IN (\'Recurring\',\'0\') THEN INVOICE_AMOUNT#(lf) ELSE 0#(lf)END as SOFTWARE_INV#(lf)#(lf)from V_ENTERPRISE_INVOICED_REVENUE", CommandTimeout=#duration(0, 1, 30, 0)]),\n #"Added Conditional Column" = Table.AddColumn(Source, "Services", each if [CLASS] = "Services" then [INVOICE_AMOUNT] else 0),\n #"Added Custom" = Table.AddColumn(#"Added Conditional Column", "Advanced New Sites", each if [PRODUCT] = "ADV"\nor [PRODUCT] = "Adv"\nthen [NEW_SITE]\nelse 0)\nin\n #"Added Custom"',
'let\n Source = Snowflake.Databases("xaa48144.snowflakecomputing.com","GSL_TEST_WH",[Role="ACCOUNTADMIN"]),\n Source2 = PostgreSQL.Database("localhost", "mics"),\n public_order_date = Source2{[Schema="public",Item="order_date"]}[Data],\n GSL_TEST_DB_Database = Source{[Name="GSL_TEST_DB",Kind="Database"]}[Data],\n PUBLIC_Schema = GSL_TEST_DB_Database{[Name="PUBLIC",Kind="Schema"]}[Data],\n SALES_ANALYST_VIEW_View = PUBLIC_Schema{[Name="SALES_ANALYST_VIEW",Kind="View"]}[Data],\n two_source_table = Table.Combine({public_order_date, SALES_ANALYST_VIEW_View})\n in\n two_source_table', 'let\n Source = Snowflake.Databases("ghh48144.snowflakefakecomputing.com","GSL_TEST_WH",[Role="ACCOUNTADMIN"]),\n Source2 = PostgreSQL.Database("localhost", "mics"),\n public_order_date = Source2{[Schema="public",Item="order_date"]}[Data],\n GSL_TEST_DB_Database = Source{[Name="GSL_TEST_DB",Kind="Database"]}[Data],\n PUBLIC_Schema = GSL_TEST_DB_Database{[Name="PUBLIC",Kind="Schema"]}[Data],\n SALES_ANALYST_VIEW_View = PUBLIC_Schema{[Name="SALES_ANALYST_VIEW",Kind="View"]}[Data],\n two_source_table = Table.Combine({public_order_date, SALES_ANALYST_VIEW_View})\n in\n two_source_table',
'let\n Source = PostgreSQL.Database("localhost" , "mics" ),\n public_order_date = Source{[Schema="public",Item="order_date"]}[Data] \n in \n public_order_date', 'let\n Source = PostgreSQL.Database("localhost" , "mics" ),\n public_order_date = Source{[Schema="public",Item="order_date"]}[Data] \n in \n public_order_date',
'let\n Source = Oracle.Database("localhost:1521/salesdb.GSLAB.COM", [HierarchicalNavigation=true]), HR = Source{[Schema="HR"]}[Data], EMPLOYEES1 = HR{[Name="EMPLOYEES"]}[Data] \n in EMPLOYEES1', 'let\n Source = Oracle.Database("localhost:1521/salesdb.GSLAB.COM", [HierarchicalNavigation=true]), HR = Source{[Schema="HR"]}[Data], EMPLOYEES1 = HR{[Name="EMPLOYEES"]}[Data] \n in EMPLOYEES1',
'let\n Source = Sql.Database("localhost", "library"),\n dbo_book_issue = Source{[Schema="dbo",Item="book_issue"]}[Data]\n in dbo_book_issue', 'let\n Source = Sql.Database("localhost", "library"),\n dbo_book_issue = Source{[Schema="dbo",Item="book_issue"]}[Data]\n in dbo_book_issue',
'let\n Source = Snowflake.Databases("xaa48144.snowflakecomputing.com","GSL_TEST_WH",[Role="ACCOUNTADMIN"]),\n GSL_TEST_DB_Database = Source{[Name="GSL_TEST_DB",Kind="Database"]}[Data],\n PUBLIC_Schema = GSL_TEST_DB_Database{[Name="PUBLIC",Kind="Schema"]}[Data],\n SALES_FORECAST_Table = PUBLIC_Schema{[Name="SALES_FORECAST",Kind="Table"]}[Data],\n SALES_ANALYST_Table = PUBLIC_Schema{[Name="SALES_ANALYST",Kind="Table"]}[Data],\n RESULT = Table.Combine({SALES_FORECAST_Table, SALES_ANALYST_Table})\n\nin\n RESULT', 'let\n Source = Snowflake.Databases("ghh48144.snowflakefakecomputing.com","GSL_TEST_WH",[Role="ACCOUNTADMIN"]),\n GSL_TEST_DB_Database = Source{[Name="GSL_TEST_DB",Kind="Database"]}[Data],\n PUBLIC_Schema = GSL_TEST_DB_Database{[Name="PUBLIC",Kind="Schema"]}[Data],\n SALES_FORECAST_Table = PUBLIC_Schema{[Name="SALES_FORECAST",Kind="Table"]}[Data],\n SALES_ANALYST_Table = PUBLIC_Schema{[Name="SALES_ANALYST",Kind="Table"]}[Data],\n RESULT = Table.Combine({SALES_FORECAST_Table, SALES_ANALYST_Table})\n\nin\n RESULT',
'let\n Source = GoogleBigQuery.Database(),\n #"seraphic-music-344307" = Source{[Name="seraphic-music-344307"]}[Data],\n school_dataset_Schema = #"seraphic-music-344307"{[Name="school_dataset",Kind="Schema"]}[Data],\n first_Table = school_dataset_Schema{[Name="first",Kind="Table"]}[Data]\nin\n first_Table', 'let\n Source = GoogleBigQuery.Database(),\n #"seraphic-music-344307" = Source{[Name="seraphic-music-344307"]}[Data],\n school_dataset_Schema = #"seraphic-music-344307"{[Name="school_dataset",Kind="Schema"]}[Data],\n first_Table = school_dataset_Schema{[Name="first",Kind="Table"]}[Data]\nin\n first_Table',
'let \nSource = GoogleBigQuery.Database([BillingProject = #"Parameter - Source"]),\n#"gcp-project" = Source{[Name=#"Parameter - Source"]}[Data],\ngcp_billing_Schema = #"gcp-project"{[Name=#"My bq project",Kind="Schema"]}[Data],\nF_GCP_COST_Table = gcp_billing_Schema{[Name="GCP_TABLE",Kind="Table"]}[Data]\nin\nF_GCP_COST_Table', 'let \nSource = GoogleBigQuery.Database([BillingProject = #"Parameter - Source"]),\n#"gcp-project" = Source{[Name=#"Parameter - Source"]}[Data],\ngcp_billing_Schema = #"gcp-project"{[Name=#"My bq project",Kind="Schema"]}[Data],\nF_GCP_COST_Table = gcp_billing_Schema{[Name="GCP_TABLE",Kind="Table"]}[Data]\nin\nF_GCP_COST_Table',
'let\n Source = GoogleBigQuery.Database([BillingProject = #"Parameter - Source"]),\n#"gcp-project" = Source{[Name=#"Parameter - Source"]}[Data],\nuniversal_Schema = #"gcp-project"{[Name="universal",Kind="Schema"]}[Data],\nD_WH_DATE_Table = universal_Schema{[Name="D_WH_DATE",Kind="Table"]}[Data],\n#"Filtered Rows" = Table.SelectRows(D_WH_DATE_Table, each [D_DATE] > #datetime(2019, 9, 10, 0, 0, 0)),\n#"Filtered Rows1" = Table.SelectRows(#"Filtered Rows", each DateTime.IsInPreviousNHours([D_DATE], 87600))\n in \n#"Filtered Rows1"', 'let\n Source = GoogleBigQuery.Database([BillingProject = #"Parameter - Source"]),\n#"gcp-project" = Source{[Name=#"Parameter - Source"]}[Data],\nuniversal_Schema = #"gcp-project"{[Name="universal",Kind="Schema"]}[Data],\nD_WH_DATE_Table = universal_Schema{[Name="D_WH_DATE",Kind="Table"]}[Data],\n#"Filtered Rows" = Table.SelectRows(D_WH_DATE_Table, each [D_DATE] > #datetime(2019, 9, 10, 0, 0, 0)),\n#"Filtered Rows1" = Table.SelectRows(#"Filtered Rows", each DateTime.IsInPreviousNHours([D_DATE], 87600))\n in \n#"Filtered Rows1"',
@ -149,6 +149,10 @@ def test_snowflake_regular_case():
assert len(data_platform_tables) == 1 assert len(data_platform_tables) == 1
assert data_platform_tables[0].name == "TESTTABLE" assert data_platform_tables[0].name == "TESTTABLE"
assert data_platform_tables[0].full_name == "PBI_TEST.TEST.TESTTABLE" assert data_platform_tables[0].full_name == "PBI_TEST.TEST.TESTTABLE"
assert (
data_platform_tables[0].datasource_server
== "bu10758.ap-unknown-2.fakecomputing.com"
)
assert ( assert (
data_platform_tables[0].data_platform_pair.powerbi_data_platform_name data_platform_tables[0].data_platform_pair.powerbi_data_platform_name
== SupportedDataPlatform.SNOWFLAKE.value.powerbi_data_platform_name == SupportedDataPlatform.SNOWFLAKE.value.powerbi_data_platform_name
@ -172,6 +176,7 @@ def test_postgres_regular_case():
assert len(data_platform_tables) == 1 assert len(data_platform_tables) == 1
assert data_platform_tables[0].name == "order_date" assert data_platform_tables[0].name == "order_date"
assert data_platform_tables[0].full_name == "mics.public.order_date" assert data_platform_tables[0].full_name == "mics.public.order_date"
assert data_platform_tables[0].datasource_server == "localhost"
assert ( assert (
data_platform_tables[0].data_platform_pair.powerbi_data_platform_name data_platform_tables[0].data_platform_pair.powerbi_data_platform_name
== SupportedDataPlatform.POSTGRES_SQL.value.powerbi_data_platform_name == SupportedDataPlatform.POSTGRES_SQL.value.powerbi_data_platform_name
@ -195,6 +200,7 @@ def test_oracle_regular_case():
assert len(data_platform_tables) == 1 assert len(data_platform_tables) == 1
assert data_platform_tables[0].name == "EMPLOYEES" assert data_platform_tables[0].name == "EMPLOYEES"
assert data_platform_tables[0].full_name == "salesdb.HR.EMPLOYEES" assert data_platform_tables[0].full_name == "salesdb.HR.EMPLOYEES"
assert data_platform_tables[0].datasource_server == "localhost:1521"
assert ( assert (
data_platform_tables[0].data_platform_pair.powerbi_data_platform_name data_platform_tables[0].data_platform_pair.powerbi_data_platform_name
== SupportedDataPlatform.ORACLE.value.powerbi_data_platform_name == SupportedDataPlatform.ORACLE.value.powerbi_data_platform_name
@ -219,6 +225,7 @@ def test_mssql_regular_case():
assert len(data_platform_tables) == 1 assert len(data_platform_tables) == 1
assert data_platform_tables[0].name == "book_issue" assert data_platform_tables[0].name == "book_issue"
assert data_platform_tables[0].full_name == "library.dbo.book_issue" assert data_platform_tables[0].full_name == "library.dbo.book_issue"
assert data_platform_tables[0].datasource_server == "localhost"
assert ( assert (
data_platform_tables[0].data_platform_pair.powerbi_data_platform_name data_platform_tables[0].data_platform_pair.powerbi_data_platform_name
== SupportedDataPlatform.MS_SQL.value.powerbi_data_platform_name == SupportedDataPlatform.MS_SQL.value.powerbi_data_platform_name
@ -259,6 +266,7 @@ def test_mssql_with_query():
assert len(data_platform_tables) == 1 assert len(data_platform_tables) == 1
assert data_platform_tables[0].name == expected_tables[index].split(".")[2] assert data_platform_tables[0].name == expected_tables[index].split(".")[2]
assert data_platform_tables[0].full_name == expected_tables[index] assert data_platform_tables[0].full_name == expected_tables[index]
assert data_platform_tables[0].datasource_server == "AUPRDWHDB"
assert ( assert (
data_platform_tables[0].data_platform_pair.powerbi_data_platform_name data_platform_tables[0].data_platform_pair.powerbi_data_platform_name
== SupportedDataPlatform.MS_SQL.value.powerbi_data_platform_name == SupportedDataPlatform.MS_SQL.value.powerbi_data_platform_name
@ -296,6 +304,10 @@ def test_snowflake_native_query():
assert len(data_platform_tables) == 1 assert len(data_platform_tables) == 1
assert data_platform_tables[0].name == expected_tables[index].split(".")[2] assert data_platform_tables[0].name == expected_tables[index].split(".")[2]
assert data_platform_tables[0].full_name == expected_tables[index] assert data_platform_tables[0].full_name == expected_tables[index]
assert (
data_platform_tables[0].datasource_server
== "bu10758.ap-unknown-2.fakecomputing.com"
)
assert ( assert (
data_platform_tables[0].data_platform_pair.powerbi_data_platform_name data_platform_tables[0].data_platform_pair.powerbi_data_platform_name
== SupportedDataPlatform.SNOWFLAKE.value.powerbi_data_platform_name == SupportedDataPlatform.SNOWFLAKE.value.powerbi_data_platform_name
@ -316,6 +328,7 @@ def test_google_bigquery_1():
assert len(data_platform_tables) == 1 assert len(data_platform_tables) == 1
assert data_platform_tables[0].name == table.full_name.split(".")[2] assert data_platform_tables[0].name == table.full_name.split(".")[2]
assert data_platform_tables[0].full_name == table.full_name assert data_platform_tables[0].full_name == table.full_name
assert data_platform_tables[0].datasource_server == "seraphic-music-344307"
assert ( assert (
data_platform_tables[0].data_platform_pair.powerbi_data_platform_name data_platform_tables[0].data_platform_pair.powerbi_data_platform_name
== SupportedDataPlatform.GOOGLE_BIGQUERY.value.powerbi_data_platform_name == SupportedDataPlatform.GOOGLE_BIGQUERY.value.powerbi_data_platform_name
@ -346,6 +359,7 @@ def test_google_bigquery_2():
assert len(data_platform_tables) == 1 assert len(data_platform_tables) == 1
assert data_platform_tables[0].name == table.full_name.split(".")[2] assert data_platform_tables[0].name == table.full_name.split(".")[2]
assert data_platform_tables[0].full_name == table.full_name assert data_platform_tables[0].full_name == table.full_name
assert data_platform_tables[0].datasource_server == "my-test-project"
assert ( assert (
data_platform_tables[0].data_platform_pair.powerbi_data_platform_name data_platform_tables[0].data_platform_pair.powerbi_data_platform_name
== SupportedDataPlatform.GOOGLE_BIGQUERY.value.powerbi_data_platform_name == SupportedDataPlatform.GOOGLE_BIGQUERY.value.powerbi_data_platform_name
@ -373,6 +387,7 @@ def test_for_each_expression_1():
assert len(data_platform_tables) == 1 assert len(data_platform_tables) == 1
assert data_platform_tables[0].name == table.full_name.split(".")[2] assert data_platform_tables[0].name == table.full_name.split(".")[2]
assert data_platform_tables[0].datasource_server == "my-test-project"
assert data_platform_tables[0].full_name == table.full_name assert data_platform_tables[0].full_name == table.full_name
assert ( assert (
data_platform_tables[0].data_platform_pair.powerbi_data_platform_name data_platform_tables[0].data_platform_pair.powerbi_data_platform_name
@ -401,6 +416,7 @@ def test_for_each_expression_2():
assert len(data_platform_tables) == 1 assert len(data_platform_tables) == 1
assert data_platform_tables[0].name == table.full_name.split(".")[2] assert data_platform_tables[0].name == table.full_name.split(".")[2]
assert data_platform_tables[0].full_name == table.full_name assert data_platform_tables[0].full_name == table.full_name
assert data_platform_tables[0].datasource_server == "dwh-prod"
assert ( assert (
data_platform_tables[0].data_platform_pair.powerbi_data_platform_name data_platform_tables[0].data_platform_pair.powerbi_data_platform_name
== SupportedDataPlatform.GOOGLE_BIGQUERY.value.powerbi_data_platform_name == SupportedDataPlatform.GOOGLE_BIGQUERY.value.powerbi_data_platform_name
@ -439,12 +455,17 @@ def test_multi_source_table():
assert len(data_platform_tables) == 2 assert len(data_platform_tables) == 2
assert data_platform_tables[0].full_name == "mics.public.order_date" assert data_platform_tables[0].full_name == "mics.public.order_date"
assert data_platform_tables[0].datasource_server == "localhost"
assert ( assert (
data_platform_tables[0].data_platform_pair.powerbi_data_platform_name data_platform_tables[0].data_platform_pair.powerbi_data_platform_name
== SupportedDataPlatform.POSTGRES_SQL.value.powerbi_data_platform_name == SupportedDataPlatform.POSTGRES_SQL.value.powerbi_data_platform_name
) )
assert data_platform_tables[1].full_name == "GSL_TEST_DB.PUBLIC.SALES_ANALYST_VIEW" assert data_platform_tables[1].full_name == "GSL_TEST_DB.PUBLIC.SALES_ANALYST_VIEW"
assert (
data_platform_tables[1].datasource_server
== "ghh48144.snowflakefakecomputing.com"
)
assert ( assert (
data_platform_tables[1].data_platform_pair.powerbi_data_platform_name data_platform_tables[1].data_platform_pair.powerbi_data_platform_name
== SupportedDataPlatform.SNOWFLAKE.value.powerbi_data_platform_name == SupportedDataPlatform.SNOWFLAKE.value.powerbi_data_platform_name
@ -467,12 +488,20 @@ def test_table_combine():
assert len(data_platform_tables) == 2 assert len(data_platform_tables) == 2
assert data_platform_tables[0].full_name == "GSL_TEST_DB.PUBLIC.SALES_FORECAST" assert data_platform_tables[0].full_name == "GSL_TEST_DB.PUBLIC.SALES_FORECAST"
assert (
data_platform_tables[0].datasource_server
== "ghh48144.snowflakefakecomputing.com"
)
assert ( assert (
data_platform_tables[0].data_platform_pair.powerbi_data_platform_name data_platform_tables[0].data_platform_pair.powerbi_data_platform_name
== SupportedDataPlatform.SNOWFLAKE.value.powerbi_data_platform_name == SupportedDataPlatform.SNOWFLAKE.value.powerbi_data_platform_name
) )
assert data_platform_tables[1].full_name == "GSL_TEST_DB.PUBLIC.SALES_ANALYST" assert data_platform_tables[1].full_name == "GSL_TEST_DB.PUBLIC.SALES_ANALYST"
assert (
data_platform_tables[1].datasource_server
== "ghh48144.snowflakefakecomputing.com"
)
assert ( assert (
data_platform_tables[1].data_platform_pair.powerbi_data_platform_name data_platform_tables[1].data_platform_pair.powerbi_data_platform_name
== SupportedDataPlatform.SNOWFLAKE.value.powerbi_data_platform_name == SupportedDataPlatform.SNOWFLAKE.value.powerbi_data_platform_name

View File

@ -1,12 +1,17 @@
import logging import logging
import sys import sys
from typing import Any, Dict from typing import Any, Dict, cast
from unittest import mock from unittest import mock
import pytest import pytest
from freezegun import freeze_time from freezegun import freeze_time
from datahub.ingestion.run.pipeline import Pipeline from datahub.ingestion.run.pipeline import Pipeline
from datahub.ingestion.source.powerbi.config import (
PowerBiDashboardSourceConfig,
SupportedDataPlatform,
)
from datahub.ingestion.source.powerbi.powerbi import PowerBiDashboardSource
from tests.test_helpers import mce_helpers from tests.test_helpers import mce_helpers
FROZEN_TIME = "2022-02-03 07:00:00" FROZEN_TIME = "2022-02-03 07:00:00"
@ -1022,3 +1027,164 @@ def test_workspace_container(
output_path=tmp_path / "powerbi_container_mces.json", output_path=tmp_path / "powerbi_container_mces.json",
golden_path=f"{test_resources_dir}/{mce_out_file}", golden_path=f"{test_resources_dir}/{mce_out_file}",
) )
def dataset_type_mapping_set_to_all_platform(pipeline: Pipeline) -> None:
source_config: PowerBiDashboardSourceConfig = cast(
PowerBiDashboardSource, pipeline.source
).source_config
assert source_config.dataset_type_mapping is not None
# Generate default dataset_type_mapping and compare it with source_config.dataset_type_mapping
default_dataset_type_mapping: dict = {}
for item in SupportedDataPlatform:
default_dataset_type_mapping[
item.value.powerbi_data_platform_name
] = item.value.datahub_data_platform_name
assert default_dataset_type_mapping == source_config.dataset_type_mapping
@freeze_time(FROZEN_TIME)
@mock.patch("msal.ConfidentialClientApplication", side_effect=mock_msal_cca)
@pytest.mark.integration
def test_dataset_type_mapping_should_set_to_all(
mock_msal, pytestconfig, tmp_path, mock_time, requests_mock
):
"""
Here we don't need to run the pipeline. We need to verify dataset_type_mapping is set to default dataplatform
"""
register_mock_api(request_mock=requests_mock)
new_config: dict = {**default_source_config()}
del new_config["dataset_type_mapping"]
pipeline = Pipeline.create(
{
"run_id": "powerbi-test",
"source": {
"type": "powerbi",
"config": {
**new_config,
},
},
"sink": {
"type": "file",
"config": {
"filename": f"{tmp_path}/powerbi_lower_case_urn_mces.json",
},
},
}
)
dataset_type_mapping_set_to_all_platform(pipeline)
@freeze_time(FROZEN_TIME)
@mock.patch("msal.ConfidentialClientApplication", side_effect=mock_msal_cca)
@pytest.mark.integration
def test_dataset_type_mapping_error(
mock_msal, pytestconfig, tmp_path, mock_time, requests_mock
):
"""
Here we don't need to run the pipeline. We need to verify if both dataset_type_mapping and server_to_platform_instance
are set then value error should get raised
"""
register_mock_api(request_mock=requests_mock)
try:
Pipeline.create(
{
"run_id": "powerbi-test",
"source": {
"type": "powerbi",
"config": {
**default_source_config(),
"server_to_platform_instance": {
"localhost": {
"platform_instance": "test",
}
},
},
},
"sink": {
"type": "file",
"config": {
"filename": f"{tmp_path}/powerbi_lower_case_urn_mces.json",
},
},
}
)
except Exception as e:
assert (
"dataset_type_mapping is deprecated. Use server_to_platform_instance only."
in str(e)
)
@freeze_time(FROZEN_TIME)
@mock.patch("msal.ConfidentialClientApplication", side_effect=mock_msal_cca)
def test_server_to_platform_map(
mock_msal, pytestconfig, tmp_path, mock_time, requests_mock
):
enable_logging()
test_resources_dir = pytestconfig.rootpath / "tests/integration/powerbi"
new_config: dict = {
**default_source_config(),
"extract_lineage": True,
"convert_lineage_urns_to_lowercase": True,
}
del new_config["dataset_type_mapping"]
new_config["server_to_platform_instance"] = {
"hp123rt5.ap-southeast-2.fakecomputing.com": {
"platform_instance": "snowflake_production_instance",
"env": "PROD",
},
"my-test-project": {
"platform_instance": "bigquery-computing-dev-account",
"env": "QA",
},
"localhost:1521": {"platform_instance": "oracle-sales-instance", "env": "PROD"},
}
register_mock_api(request_mock=requests_mock)
output_path: str = f"{tmp_path}/powerbi_server_to_platform_instance_mces.json"
pipeline = Pipeline.create(
{
"run_id": "powerbi-test",
"source": {
"type": "powerbi",
"config": new_config,
},
"sink": {
"type": "file",
"config": {
"filename": output_path,
},
},
}
)
pipeline.run()
pipeline.raise_from_status()
golden_file_path: str = (
f"{test_resources_dir}/golden_test_server_to_platform_instance.json"
)
mce_helpers.check_golden_file(
pytestconfig,
output_path=output_path,
golden_path=golden_file_path,
)
# As server_to_platform_instance map is provided, the old dataset_type_mapping
# should be set to all supported platform
# to process all available upstream lineage even if mapping for platform instance is
# not provided in server_to_platform_instance map
dataset_type_mapping_set_to_all_platform(pipeline)