-
Notifications
You must be signed in to change notification settings - Fork 99
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow custom granularity names in string name to struct conversion #1387
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,6 +7,8 @@ | |
from dbt_semantic_interfaces.type_enums.date_part import DatePart | ||
from dbt_semantic_interfaces.type_enums.time_granularity import TimeGranularity | ||
|
||
from metricflow_semantics.time.granularity import ExpandedTimeGranularity | ||
|
||
DUNDER = "__" | ||
|
||
logger = logging.getLogger(__name__) | ||
|
@@ -24,9 +26,36 @@ class StructuredLinkableSpecName: | |
|
||
entity_link_names: Tuple[str, ...] | ||
element_name: str | ||
time_granularity: Optional[TimeGranularity] = None | ||
time_granularity_name: Optional[str] = None | ||
date_part: Optional[DatePart] = None | ||
|
||
def __post_init__(self) -> None: | ||
"""Post init method to ensure all name values are lower-case. | ||
|
||
This implies that all values in the TimeGranularity enumeration must be lower-case. | ||
""" | ||
assert self.element_name.lower() == self.element_name, ( | ||
f"Element name {self.element_name} is not all lower-case. This should have been addressed at model " | ||
"parse time!" | ||
) | ||
assert all([link_name.lower() == link_name for link_name in self.entity_link_names]), ( | ||
f"Found entity link name that includes upper-case letters. Entity link names: {self.entity_link_names}. " | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this enforced already? That entity names must be lowercase? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In theory, yes. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Excellent! And a helpful link pointing me to how to add this validation for custom granularities too 🙃 |
||
"This should have been addressed at model parse time!" | ||
) | ||
|
||
if self.time_granularity_name: | ||
is_standard_name = ExpandedTimeGranularity.is_standard_granularity_name(self.time_granularity_name) | ||
if is_standard_name: | ||
follow_up = ( | ||
"This indicates a bug where someone added a non-lowercase value to the TimeGranularity " | ||
"enum in dbt-semantic-interfaces!" | ||
) | ||
else: | ||
follow_up = "This should have been addressed at model parse time!" | ||
assert ( | ||
self.time_granularity_name.lower() == self.time_granularity_name | ||
), f"The time_granularity_name {self.time_granularity_name} includes upper-case letters. {follow_up}" | ||
|
||
@staticmethod | ||
def from_name(qualified_name: str) -> StructuredLinkableSpecName: | ||
"""Construct from a name e.g. listing__ds__month.""" | ||
|
@@ -43,6 +72,7 @@ def from_name(qualified_name: str) -> StructuredLinkableSpecName: | |
) | ||
|
||
associated_granularity = None | ||
# TODO: [custom granularity] Update parsing to account for custom granularities | ||
for granularity in TimeGranularity: | ||
if name_parts[-1] == granularity.value: | ||
associated_granularity = granularity | ||
|
@@ -52,13 +82,13 @@ def from_name(qualified_name: str) -> StructuredLinkableSpecName: | |
# e.g. "ds__month" | ||
if len(name_parts) == 2: | ||
return StructuredLinkableSpecName( | ||
entity_link_names=(), element_name=name_parts[0], time_granularity=associated_granularity | ||
entity_link_names=(), element_name=name_parts[0], time_granularity_name=associated_granularity.value | ||
) | ||
# e.g. "messages__ds__month" | ||
return StructuredLinkableSpecName( | ||
entity_link_names=tuple(name_parts[:-2]), | ||
element_name=name_parts[-2], | ||
time_granularity=associated_granularity, | ||
time_granularity_name=associated_granularity.value, | ||
) | ||
|
||
# e.g. "messages__ds" | ||
|
@@ -74,8 +104,8 @@ def qualified_name(self) -> str: | |
items = list(self.entity_link_names) + [self.element_name] | ||
if self.date_part: | ||
items.append(self.date_part_suffix(date_part=self.date_part)) | ||
elif self.time_granularity: | ||
items.append(self.time_granularity.value) | ||
elif self.time_granularity_name: | ||
items.append(self.time_granularity_name) | ||
return DUNDER.join(items) | ||
|
||
@property | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This means that custom granularities will be required to be lowercase. Is that a necessary restriction?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In my opinion, yes. We do not want
Fortnight
andfortnight
to mean different things in the same model. But also this this the standard we've used for ages.