Feat: Adds support for macros in model_defaults and conditional properties#3933
Feat: Adds support for macros in model_defaults and conditional properties#3933themisvaltinos merged 10 commits intomainfrom
Conversation
84049c1 to
b31eeaf
Compare
|
Thanks @izeigerman addressed comments and generalised logic for all model defaults and rendering of the three kind of properties during runtime for consistency, if you want to have another look |
| def render_physical_properties(self, **render_kwargs: t.Any) -> t.Dict[str, t.Any]: | ||
| return self.render_properties(properties=self.physical_properties, **render_kwargs) | ||
|
|
||
| def render_virtual_properties(self, **render_kwargs: t.Any) -> t.Dict[str, t.Any]: |
There was a problem hiding this comment.
@erindru didn't you argue that virtual properties should be rendered at load time?
There was a problem hiding this comment.
I think we were discussing that for virtual properties there wasn't a use case for it yet like a specific use case for physical_properties so they don't have to be rendered at runtime. Unless you think @erindru that indeed virtual properties should be rendered at load time?
There was a problem hiding this comment.
I dont have a strong opinion. I needed physical_properties to be rendered at creation/evaluation time because I needed access to @this_model for a specific use case, but I didn't touch virtual_properties at the time because there was no clear reason to.
There was a problem hiding this comment.
Right I don't have a strong opinion either, this allows the use of this_model or model_kind_name in virtual properties as well, but at the same time I don't know how this could be helpful or what property it will make sense to unset. So happy to move it back to load time
sqlmesh/core/config/model.py
Outdated
| allow_partials: t.Optional[bool] = None | ||
| interval_unit: t.Optional[IntervalUnit] = None | ||
| enabled: t.Optional[bool] = None | ||
| optimize_query: t.Optional[t.Any] = None |
There was a problem hiding this comment.
Why did we erase the types entirely? Shouldn't they be t.Union[str, bool] etc?
There was a problem hiding this comment.
When do we validate that the value passed here is correct?
There was a problem hiding this comment.
Yes you're right will need to adjust the type and add validation somewhere. I suppose after the rendering since it can't occur before resolving the macros
There was a problem hiding this comment.
Revised it and added validation so that after rendering the values to raise if the values are not of the correct type
4ab8efc to
9402ec6
Compare
|
Addressed comments @izeigerman regarding |
338c20a to
db7c331
Compare
sqlmesh/core/model/definition.py
Outdated
|
|
||
| def render_physical_properties(self, **render_kwargs: t.Any) -> t.Dict[str, exp.Expression]: | ||
| def _render(expression: exp.Expression) -> exp.Expression: | ||
| def render_properties( |
There was a problem hiding this comment.
Shouldn't this be private?
sqlmesh/core/model/definition.py
Outdated
| raise SQLMeshError( | ||
| f"Failed to render model attribute `{fields['name']}` at `{path}`\n" | ||
| f"'{expression.sql(dialect=dialect)}' must return an expression" | ||
| # Warn instead of raising for cases where an attribute is conditionally assigned |
There was a problem hiding this comment.
I don't think we support this behavior for all meta fields, are we not? Eg. if the macro returns NULL for something like allow_partials we do want to fail, don't we? Should we then distinguish between macro not returning anything and macro returning NULL? The former could be a bug, the latter seems intentional.
There was a problem hiding this comment.
Looks like this validation happens later in render_model_defaults. Please correct me if I'm wrong
There was a problem hiding this comment.
Right the validation happens in render_model_defaults and it will be a bug if the rendering didn't return anything at all here, so revised to error out in that case and not for the intentional set to null by the user
sqlmesh/core/snapshot/evaluator.py
Outdated
| table_description=model.description if is_prod else None, | ||
| column_descriptions=model.column_descriptions if is_prod else None, | ||
| view_properties=model.virtual_properties, | ||
| view_properties=model.render_virtual_properties(**kwargs), |
There was a problem hiding this comment.
Let's not use kwargs. Let's make an explicit dict render_kwargs instead.
There was a problem hiding this comment.
Sure revised this
izeigerman
left a comment
There was a problem hiding this comment.
Please address the remaining comments. LGTM otherwise
…l_kind_name macro
db7c331 to
6e15835
Compare
This update adds:
model_defaultsattributes.physical_properties,session_properties,virtual_properties.session_properties,virtual_propertiesrendering is now moved to runtime to align withphysical_properties.model_kind_namemacro variable, which holds the name of the current model kind.This macro is intended for example to disable from
physical_propertiesthecreatable_typefor your project's VIEW-type models and set it toTRANSIENTfor the rest of the model kinds, by having inmodel_defaults: