Skip to content

Commit db507bc

Browse files
Feat: Adds support for macros in model_defaults and conditional properties (#3933)
1 parent b608d95 commit db507bc

8 files changed

Lines changed: 553 additions & 58 deletions

File tree

docs/concepts/macros/macro_variables.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,3 +134,4 @@ SQLMesh provides two other predefined variables used to modify model behavior ba
134134
* Can be used in model definitions when SQLGlot cannot fully parse a statement and you need to reference the model's underlying physical table directly.
135135
* Can be passed as an argument to macros that access or interact with the underlying physical table.
136136
* @this_env - A string value containing the name of the current [environment](../environments.md). Only available in [`before_all` and `after_all` statements](../../guides/configuration.md#before_all-and-after_all-statements), as well as in macros invoked within them.
137+
* @model_kind_name - A string value containing the name of the current model kind. Intended to be used in scenarios where you need to control the [physical properties in model defaults](../../reference/model_configuration.md#model-defaults).

docs/reference/model_configuration.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,34 @@ To override `partition_expiration_days`, add a new `creatable_type` property and
107107
)
108108
```
109109

110+
You can also use the `@model_kind_name` variable to fine-tune control over `physical_properties` in `model_defaults`. This holds the current model's kind name and is useful for conditionally assigning a property. For example, to disable `creatable_type` for your project's `VIEW` kind models:
111+
112+
=== "YAML"
113+
114+
```yaml linenums="1"
115+
model_defaults:
116+
dialect: snowflake
117+
start: 2022-01-01
118+
physical_properties:
119+
creatable_type: "@IF(@model_kind_name != 'VIEW', 'TRANSIENT', NULL)"
120+
```
121+
122+
=== "Python"
123+
124+
```python linenums="1"
125+
from sqlmesh.core.config import Config, ModelDefaultsConfig
126+
127+
config = Config(
128+
model_defaults=ModelDefaultsConfig(
129+
dialect="snowflake",
130+
start="2022-01-01",
131+
physical_properties={
132+
"creatable_type": "@IF(@model_kind_name != 'VIEW', 'TRANSIENT', NULL)",
133+
},
134+
),
135+
)
136+
```
137+
110138

111139
The SQLMesh project-level `model_defaults` key supports the following options, described in the [general model properties](#general-model-properties) table above:
112140

sqlmesh/core/config/model.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@
1010
model_kind_validator,
1111
on_destructive_change_validator,
1212
)
13+
from sqlmesh.core.model.meta import FunctionCall
1314
from sqlmesh.core.node import IntervalUnit
1415
from sqlmesh.utils.date import TimeLike
15-
from sqlmesh.core.model.meta import FunctionCall
1616
from sqlmesh.utils.pydantic import field_validator
1717

1818

@@ -56,10 +56,10 @@ class ModelDefaultsConfig(BaseConfig):
5656
virtual_properties: t.Optional[t.Dict[str, t.Any]] = None
5757
session_properties: t.Optional[t.Dict[str, t.Any]] = None
5858
audits: t.Optional[t.List[FunctionCall]] = None
59-
optimize_query: t.Optional[bool] = None
60-
allow_partials: t.Optional[bool] = None
61-
interval_unit: t.Optional[IntervalUnit] = None
62-
enabled: t.Optional[bool] = None
59+
optimize_query: t.Optional[t.Union[str, bool]] = None
60+
allow_partials: t.Optional[t.Union[str, bool]] = None
61+
interval_unit: t.Optional[t.Union[str, IntervalUnit]] = None
62+
enabled: t.Optional[t.Union[str, bool]] = None
6363

6464
_model_kind_validator = model_kind_validator
6565
_on_destructive_change_validator = on_destructive_change_validator

sqlmesh/core/model/decorator.py

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@
1818
create_sql_model,
1919
create_models_from_blueprints,
2020
get_model_name,
21+
parse_defaults_properties,
2122
render_meta_fields,
23+
render_model_defaults,
2224
)
2325
from sqlmesh.core.model.kind import ModelKindName, _ModelKind
2426
from sqlmesh.utils import registry_decorator, DECORATOR_RETURN_TYPE
@@ -159,8 +161,25 @@ def model(
159161
if isinstance(rendered_name, exp.Expression):
160162
rendered_fields["name"] = rendered_name.sql(dialect=dialect)
161163

164+
rendered_defaults = (
165+
render_model_defaults(
166+
defaults=defaults,
167+
module_path=module_path,
168+
macros=macros,
169+
jinja_macros=jinja_macros,
170+
variables=variables,
171+
path=path,
172+
dialect=dialect,
173+
default_catalog=default_catalog,
174+
)
175+
if defaults
176+
else {}
177+
)
178+
179+
rendered_defaults = parse_defaults_properties(rendered_defaults, dialect=dialect)
180+
162181
common_kwargs = {
163-
"defaults": defaults,
182+
"defaults": rendered_defaults,
164183
"path": path,
165184
"time_column_format": time_column_format,
166185
"python_env": serialize_env(env, path=module_path),

0 commit comments

Comments
 (0)