def test_api_model_join_from_internal(): model_join = ModelJoin({ 'join_type': JoinType.left, 'to_model': prefix_with_virtual_data_source(_VIRTUAL_DATA_SOURCE, 'model_1'), 'taxons': [ prefix_with_virtual_data_source(_VIRTUAL_DATA_SOURCE, 'taxon_slug'), prefix_with_virtual_data_source(_VIRTUAL_DATA_SOURCE, 'taxon_slug_2'), ], 'relationship': Relationship.many_to_one, }) api_join = FdqModelJoinMapper.from_internal(model_join, _VIRTUAL_DATA_SOURCE) assert api_join.dict(by_alias=True) == { 'join_type': api_join.join_type, 'to_model': remove_virtual_data_source_prefix(_VIRTUAL_DATA_SOURCE, model_join.to_model), 'relationship': FdqModelJoinRelationship(api_join.relationship.value), 'fields': [ remove_virtual_data_source_prefix(_VIRTUAL_DATA_SOURCE, taxon) for taxon in model_join.taxons ], }
def time_granularity(self) -> Optional[TimeGranularity]: """ Time granularity of model's data (if it can be inferred) """ date_taxon_slug = prefix_with_virtual_data_source(self.data_source, TaxonSlugs.DATE) date_hour_taxon_slug = prefix_with_virtual_data_source(self.data_source, TaxonSlugs.DATE_HOUR) if self.has_taxon(date_taxon_slug): return TimeGranularity.day elif self.has_taxon(date_hour_taxon_slug): return TimeGranularity.hour return None
def to_internal(cls, model: FdqModel, virtual_data_source: str, company_id: str) -> HuskyModel: """ Creates HuskyModel from FdqModel :return: Correct HuskyModel """ identifiers = set(model.identifiers) data = { 'name': prefix_with_virtual_data_source(virtual_data_source, model.model_name).lower(), 'data_sources': [virtual_data_source], 'model_type': HuskyModelType.METRIC, 'fully_qualified_name_parts': model.data_source.split('.'), 'visibility': model.visibility, 'company_id': company_id, 'attributes': { attr.taxon: attr for api_attr in model.attributes for attr in FdqModelAttributeMapper.to_internal( api_attr, virtual_data_source, identifiers) }, 'joins': [ FdqModelJoinMapper.to_internal(join, virtual_data_source) for join in model.joins ], } inst = HuskyModel(data) return inst
def test_api_model_to_internal(api_model): husky_model = FdqModelMapper.to_internal(api_model, _VIRTUAL_DATA_SOURCE, 'company_id') assert husky_model.to_primitive() == { 'data_sources': [_VIRTUAL_DATA_SOURCE], 'fully_qualified_name_parts': api_model.data_source.split('.'), 'model_type': 'metric', 'attributes': { attr.taxon: attr.to_primitive() for api_attr in api_model.attributes for attr in FdqModelAttributeMapper.to_internal( api_attr, _VIRTUAL_DATA_SOURCE, set(api_model.identifiers)) }, 'company_id': 'company_id', 'joins': [ FdqModelJoinMapper.to_internal( join, _VIRTUAL_DATA_SOURCE).to_primitive() for join in api_model.joins ], 'name': prefix_with_virtual_data_source(_VIRTUAL_DATA_SOURCE, api_model.model_name), 'project_id': None, 'visibility': api_model.visibility.name, }
def result(self, context: TelRootContext) -> TelQueryResult: sql_expression = literal_column( context.tel_dialect.model.taxon_sql_accessor( context.husky_context, prefix_with_virtual_data_source(context.tel_dialect.virtual_data_source, self._slug), False, context.tel_dialect, ) ) return TelQueryResult(sql_expression, context.husky_dialect)
def to_internal(cls, join: FdqModelJoin, virtual_data_source: str) -> ModelJoin: """ Initialize model attribute for Husky model from API model attribute and add virtual data source taxon slug, if needed """ return ModelJoin({ 'join_type': join.join_type.value, # TODO ? make sure that "to_model" exists 'to_model': prefix_with_virtual_data_source(virtual_data_source, join.to_model).lower(), 'relationship': join.relationship.value, 'taxons': [ prefix_with_virtual_data_source(virtual_data_source, taxon).lower() for taxon in join.taxons ], })
def test_api_model_join_to_internal(): api_join = FdqModelJoin( join_type=JoinType.left, to_model='model_1', fields=['taxon_slug', 'taxon_slug_2'], relationship=FdqModelJoinRelationship.many_to_one, ) model_join = FdqModelJoinMapper.to_internal(api_join, _VIRTUAL_DATA_SOURCE) assert model_join.to_primitive() == { 'direction': None, 'join_type': api_join.join_type.value, 'to_model': prefix_with_virtual_data_source(_VIRTUAL_DATA_SOURCE, api_join.to_model), 'relationship': api_join.relationship.value, 'taxons': [ prefix_with_virtual_data_source(_VIRTUAL_DATA_SOURCE, taxon) for taxon in api_join.taxons ], }
def test_api_model_attribute_to_internal(model_attr): identifiers = {'taxon_slug'} attrs = FdqModelAttributeMapper.to_internal(model_attr, _VIRTUAL_DATA_SOURCE, identifiers) assert [attr.to_primitive() for attr in attrs] == [{ 'tel_transformation': model_attr.data_reference, 'taxon': prefix_with_virtual_data_source(_VIRTUAL_DATA_SOURCE, model_attr.field_map[0]), 'identifier': model_attr.field_map[0] in identifiers, 'quantity_type': ValueQuantityType.scalar.value, }]
def to_internal(cls, attr: FdqModelAttribute, virtual_data_source: str, identifiers: Set[str]) -> List[ModelAttribute]: """ Initialize model attribute for Husky model from API model attribute and add virtual data source taxon slug, if needed """ attrs = [] for taxon_slug in attr.field_map: attrs.append( ModelAttribute({ 'tel_transformation': attr.data_reference, 'taxon': prefix_with_virtual_data_source(virtual_data_source, taxon_slug).lower(), 'identifier': taxon_slug in identifiers, })) return attrs
@pytest.mark.parametrize( 'husky_model', [ HuskyModel({ 'data_sources': [_VIRTUAL_DATA_SOURCE], 'fully_qualified_name_parts': ['physical', 'db', 'schema', 'table'], 'model_type': 'metric', 'attributes': {}, 'company_id': _COMPANY_ID, 'joins': [], 'name': prefix_with_virtual_data_source(_VIRTUAL_DATA_SOURCE, 'husky_name_slug'), 'visibility': ModelVisibility.hidden, }), HuskyModel({ 'name': prefix_with_virtual_data_source(_VIRTUAL_DATA_SOURCE, 'api-model-slug-2'), 'data_sources': [_VIRTUAL_DATA_SOURCE], 'fully_qualified_name_parts': ['physical', 'db', 'table2'], 'company_id': _COMPANY_ID, 'attributes': { prefix_with_virtual_data_source(_VIRTUAL_DATA_SOURCE, 'taxon_slug'): { 'tel_transformation':
def test_prefix_with_virtual_data_source(): slug = prefix_with_virtual_data_source('virtual', 'virtual_taxon_slug') assert slug == 'virtual|virtual_taxon_slug'
def test_prefix_with_virtual_data_source_fails(vs, slug): with pytest.raises(WrongVirtualDataSource): prefix_with_virtual_data_source(vs, slug)