Skip to content

Feat: Adds support for macros in model_defaults and conditional properties#3933

Merged
themisvaltinos merged 10 commits intomainfrom
themis/props_parametrisation
Mar 12, 2025
Merged

Feat: Adds support for macros in model_defaults and conditional properties#3933
themisvaltinos merged 10 commits intomainfrom
themis/props_parametrisation

Conversation

@themisvaltinos
Copy link
Contributor

@themisvaltinos themisvaltinos commented Mar 4, 2025

This update adds:

  • Macro support in model_defaults attributes.
  • The ability to conditionally enable these, as well as for physical_properties, session_properties, virtual_properties.
  • For session_properties, virtual_properties rendering is now moved to runtime to align with physical_properties.
  • Introduces the model_kind_name macro variable, which holds the name of the current model kind.

This macro is intended for example to disable from physical_properties the creatable_type for your project's VIEW-type models and set it to TRANSIENT for the rest of the model kinds, by having in model_defaults:

model_defaults:
  dialect: snowflake
  start: 2022-01-01
  physical_properties:
    creatable_type: "@IF(@model_kind_name != 'VIEW', 'TRANSIENT', NULL)"

@themisvaltinos themisvaltinos requested a review from a team March 4, 2025 12:42
@themisvaltinos themisvaltinos force-pushed the themis/props_parametrisation branch 2 times, most recently from 84049c1 to b31eeaf Compare March 6, 2025 07:38
@themisvaltinos themisvaltinos changed the title Feat: Add support for conditional physical_properties, add model_kind_name macro Feat: Adds support for macros in model_defaults and conditional properties Mar 6, 2025
@themisvaltinos
Copy link
Contributor Author

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]:
Copy link
Collaborator

Choose a reason for hiding this comment

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

@erindru didn't you argue that virtual properties should be rendered at load time?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

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?

Copy link
Collaborator

Choose a reason for hiding this comment

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

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.

Copy link
Contributor Author

@themisvaltinos themisvaltinos Mar 7, 2025

Choose a reason for hiding this comment

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

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

allow_partials: t.Optional[bool] = None
interval_unit: t.Optional[IntervalUnit] = None
enabled: t.Optional[bool] = None
optimize_query: t.Optional[t.Any] = None
Copy link
Collaborator

Choose a reason for hiding this comment

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

Why did we erase the types entirely? Shouldn't they be t.Union[str, bool] etc?

Copy link
Collaborator

Choose a reason for hiding this comment

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

When do we validate that the value passed here is correct?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

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

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Revised it and added validation so that after rendering the values to raise if the values are not of the correct type

@themisvaltinos themisvaltinos force-pushed the themis/props_parametrisation branch from 4ab8efc to 9402ec6 Compare March 7, 2025 17:27
@themisvaltinos
Copy link
Contributor Author

Addressed comments @izeigerman regarding virtual_properties and session_properties let me know if you'd prefer to move them back to loading time

@themisvaltinos themisvaltinos force-pushed the themis/props_parametrisation branch from 338c20a to db7c331 Compare March 8, 2025 17:08

def render_physical_properties(self, **render_kwargs: t.Any) -> t.Dict[str, exp.Expression]:
def _render(expression: exp.Expression) -> exp.Expression:
def render_properties(
Copy link
Collaborator

Choose a reason for hiding this comment

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

Shouldn't this be private?

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
Copy link
Collaborator

Choose a reason for hiding this comment

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

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.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Looks like this validation happens later in render_model_defaults. Please correct me if I'm wrong

Copy link
Contributor Author

Choose a reason for hiding this comment

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

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

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),
Copy link
Collaborator

Choose a reason for hiding this comment

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

Let's not use kwargs. Let's make an explicit dict render_kwargs instead.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sure revised this

Copy link
Collaborator

@izeigerman izeigerman left a comment

Choose a reason for hiding this comment

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

Please address the remaining comments. LGTM otherwise

@themisvaltinos themisvaltinos force-pushed the themis/props_parametrisation branch from db7c331 to 6e15835 Compare March 12, 2025 04:51
@themisvaltinos themisvaltinos merged commit db507bc into main Mar 12, 2025
22 checks passed
@themisvaltinos themisvaltinos deleted the themis/props_parametrisation branch March 12, 2025 05:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants