Skip to content
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

Adding metric expression validation #5873

Merged
merged 5 commits into from
Sep 27, 2022
Merged

Conversation

callum-mcdata
Copy link
Contributor

resolves #5871

Description

  • changing default value for expression to None
  • Adding test to confirm behavior

Checklist

  • I have read the contributing guide and understand what's expected of me
  • I have signed the CLA
  • I have run this code in development and it appears to resolve the stated issue
  • This PR includes tests, or tests are not required/relevant for this PR
  • I have run changie new to create a changelog entry

@cla-bot cla-bot bot added the cla:yes label Sep 16, 2022
@github-actions
Copy link
Contributor

Thank you for your pull request! We could not find a changelog entry for this change. For details on how to document a change, see the contributing guide.

@callum-mcdata
Copy link
Contributor Author

Interesting. I seem to be getting this error from the code quality check

error: Incompatible types in assignment (expression has type "None", variable has type "Union[str, int]") [assignment]

Is this method of implementation not correct? I suppose I could keep it the same and add another test under the validate function but that feels like we'd be building too many patterns into the function instead of having it live in the spec itself?

@@ -476,7 +476,7 @@ class UnparsedMetric(dbtClassMixin, Replaceable):
calculation_method: str
timestamp: str
description: str = ""
expression: Union[str, int] = ""
expression: Union[str, int] = None
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@callum-mcdata I think you need to make the same change to ParsedMetric as well. Hoping that resolves the mypy error (though never guaranteed)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jtcohen6 am I misunderstanding the ParsedMetric? The expression attribute is set to expression: str, which makes sense because I would think that enforces that it must be a string. I was hoping that the change to unparsed metric would then cause a None from UnparsedMetric to fail the requirement of string for ParsedMetric

Copy link
Contributor

@jtcohen6 jtcohen6 Sep 23, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@callum-mcdata Ah, I understand now. The problem is that the field needs to be Optional[] in order to have default None. And we actually don't want it to be optional, or ever None!

Two options here:

  1. Leaving it as is, but adding a check in UnparsedMetric.validate() that raises a nice exception if expression is missing/None (after rename_metric_attr is handled of course)
  2. Change the type to match exactly what's in ParsedMetric, that is a str field with no default (= required):
    expression: str
    description: str = ""

Those two have to be reordered, because required fields need to come before optional fields with defaults

I don't see any mypy errors because the types now match exactly. And when I define a metric that's missing expression + sql (old name), This is the exception I now see:

dbt.exceptions.ParsingException: Parsing Error
  Invalid metrics config given in FilePath(searched_path='models', relative_path='my_metric.yml', modification_time=1663957848.4168892, project_root='/Users/jerco/dev/scratch/testy') @ metrics: {'name': 'new_customers', 'label': 'New Customers', 'model': "ref('my_model')", 'description': 'The number of paid customers using the product', 'timestamp': 'signup_date', 'time_grains': ['day', 'week', 'month'], 'dimensions': ['plan', 'country'], 'filters': [{'field': 'is_paying', 'operator': 'is', 'value': 'true'}, {'field': 'lifetime_value', 'operator': '>=', 'value': '100'}, {'field': 'company_name', 'operator': '!=', 'value': "'Acme, Inc'"}, {'field': 'signup_date', 'operator': '>=', 'value': "'2020-01-01'"}], 'calculation_method': 'count'} - at path []: 'expression' is a required property

Could be nicer, but unfortunately that's our standard hologram validation error message 🤷

(Do you know why we added int as an option in #5027? Is expression ever an int?)

Copy link
Contributor Author

@callum-mcdata callum-mcdata Sep 26, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got it. For sake of clean error messages, I'm leaning towards option 1 even though I don't like the idea of adding more things to the custom validate Strike that, I actually think option 2 is better. The error messages are not pretty but they fit into the broader form of how we validate. Let me take a stab at this today and let you know how it goes!

As for the int function - I think it was to support things like "field + 1"? I'm not entirely sure though

@callum-mcdata
Copy link
Contributor Author

@jtcohen6 I went with the second option and additionally removed the Union[str,int] designation in UnparsedMetric. It passed all of the tests that we have in dbt core and just to make sure I ran it through the test suite in dbt_metrics as well. So assuming all the above tests complete we should be good to go!

@callum-mcdata callum-mcdata marked this pull request as ready for review September 26, 2022 16:44
@callum-mcdata callum-mcdata requested review from a team as code owners September 26, 2022 16:44
@leahwicz leahwicz requested a review from gshank September 26, 2022 16:47
Copy link
Member

@emmyoop emmyoop left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good. If you can just update the test comment I can merge it in for you.

tests/functional/metrics/test_metrics.py Outdated Show resolved Hide resolved
Copy link
Contributor

@colin-rogers-dbt colin-rogers-dbt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@gshank gshank merged commit 17aca39 into main Sep 27, 2022
@gshank gshank deleted the adding_expression_validation branch September 27, 2022 16:38
@jtcohen6 jtcohen6 added the semantic Issues related to the semantic layer label Jun 20, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cla:yes semantic Issues related to the semantic layer
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[CT-1201] [Bug] Metrics don't require expression field
5 participants