Skip to content

Commit 4e60e2c

Browse files
committed
Config: add project-index default for render
Signed-off-by: Andreas Fredhøi <andreas.fredhoi@fresio.no>
1 parent e18a83d commit 4e60e2c

11 files changed

Lines changed: 98 additions & 9 deletions

File tree

docs/examples/sqlmesh_cli_crash_course.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -738,6 +738,11 @@ You'll use these commands as needed to validate that your changes are behaving a
738738

739739
This is a great way to verify that your model's SQL is looking as expected before applying the changes. It is especially important if you're migrating from one query engine to another (ex: postgres to databricks).
740740

741+
In large projects, add `--use-project-index` to load only the model being rendered and its upstream
742+
dependencies. To enable this behavior by default, set
743+
[`render.use_project_index`](../reference/configuration.md#render) to `true` in the project
744+
configuration.
745+
741746
=== "SQLMesh"
742747

743748
```bash
@@ -1254,4 +1259,4 @@ If you notice you have a lot of old development schemas/data, you can clean them
12541259

12551260
```bash
12561261
tcloud sqlmesh janitor
1257-
```
1262+
```

docs/guides/configuration.md

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ The `config` sub-module API documentation describes the individual classes used
9090
- [Connection configuration](https://sqlmesh.readthedocs.io/en/latest/_readthedocs/html/sqlmesh/core/config/connection.html) (separate classes for each supported database/engine)
9191
- [Scheduler configuration](https://sqlmesh.readthedocs.io/en/latest/_readthedocs/html/sqlmesh/core/config/scheduler.html) (separate classes for each supported scheduler)
9292
- [Plan change categorization configuration](https://sqlmesh.readthedocs.io/en/latest/_readthedocs/html/sqlmesh/core/config/categorizer.html#CategorizerConfig): `CategorizerConfig()`
93+
- [Render configuration](https://sqlmesh.readthedocs.io/en/latest/_readthedocs/html/sqlmesh/core/config/render.html): `RenderConfig()`
9394
- [User configuration](https://sqlmesh.readthedocs.io/en/latest/_readthedocs/html/sqlmesh/core/user.html#User): `User()`
9495
- [Notification configuration](https://sqlmesh.readthedocs.io/en/latest/_readthedocs/html/sqlmesh/core/notification_target.html) (separate classes for each notification target)
9596

@@ -331,7 +332,7 @@ The cache directory is automatically created if it doesn't exist. You can clear
331332

332333
#### Project index
333334

334-
The `--use-project-index` option on supported commands maintains a persistent model dependency index in the cache directory. Each project writes a file named `<project>_<hash>_model_index.json`.
335+
The `--use-project-index` option on the `lint` and `render` commands maintains a persistent model dependency index in the cache directory. Each project writes a file named `<project>_<hash>_model_index.json`. The option can be enabled by default for each command with `linter.use_project_index` or `render.use_project_index`, respectively.
335336

336337
A full project load with the option enabled creates or refreshes the index. SQLMesh invalidates it when relevant configuration, gateway, macro, audit, or signal metadata changes, or when the set of model files changes. If the index is missing, invalid, or stale, SQLMesh safely falls back to a full project load and rebuilds it.
337338

@@ -1503,6 +1504,35 @@ SQLMesh provides a linter that checks for potential issues in your models' code.
15031504

15041505
Learn more about linting configuration in the [linting guide](./linter.md).
15051506

1507+
### Rendering
1508+
1509+
By default, `sqlmesh render` loads every model in the project. In large projects, you can use the
1510+
persistent project index to load only the model being rendered and its transitive upstream
1511+
dependencies. Enable indexed rendering for an individual command with `--use-project-index`, or
1512+
make it the project default with the `render.use_project_index` configuration option.
1513+
1514+
=== "YAML"
1515+
1516+
```yaml linenums="1"
1517+
render:
1518+
use_project_index: true
1519+
```
1520+
1521+
=== "Python"
1522+
1523+
```python linenums="1"
1524+
from sqlmesh.core.config import Config, ModelDefaultsConfig, RenderConfig
1525+
1526+
config = Config(
1527+
model_defaults=ModelDefaultsConfig(dialect="duckdb"),
1528+
render=RenderConfig(use_project_index=True),
1529+
)
1530+
```
1531+
1532+
`Context.render` uses the configured value when `use_project_index` is omitted. Passing
1533+
`use_project_index=False` explicitly disables indexed rendering for that API call. See the
1534+
[`render` CLI reference](../reference/cli.md#render) for the other rendering options.
1535+
15061536
### Debug mode
15071537

15081538
To enable debug mode set the `SQLMESH_DEBUG` environment variable to one of the following values: "1", "true", "t", "yes" or "y".

docs/reference/cli.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -449,7 +449,8 @@ Options:
449449
--no-format Disable fancy formatting of the query.
450450
--use-project-index Use the persistent project index to load and
451451
render only the target model and its upstream
452-
dependencies.
452+
dependencies. Can also be enabled with
453+
render.use_project_index.
453454
--max-text-width INTEGER The max number of characters in a segment before
454455
creating new lines in pretty mode.
455456
--leading-comma Determines whether or not the comma is leading

docs/reference/configuration.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,12 @@ See all the keys allowed in `model_defaults` at the [model configuration referen
6767
| `linter.enabled` | Whether linting is enabled (Default: `False`) | boolean | N |
6868
| `linter.use_project_index` | Whether to use the persistent project index for linting. Targeted linting loads selected models and their upstream dependencies. (Default: `False`) | boolean | N |
6969

70+
### Render
71+
72+
| Option | Description | Type | Required |
73+
|----------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------|----------|
74+
| `render.use_project_index` | Whether to use the persistent project index when rendering. Only the target model and its upstream dependencies are loaded. (Default: `False`) | boolean | N |
75+
7076
### Variables
7177

7278
The `variables` key can be used to provide values for user-defined variables, accessed using the [`@VAR` macro function](../concepts/macros/sqlmesh_macros.md#global-variables) in SQL model definitions, [`context.var` method](../concepts/models/python_models.md#global-variables) in Python model definitions, and [`evaluator.var` method](../concepts/macros/sqlmesh_macros.md#accessing-global-variable-values) in Python macro functions.

sqlmesh/cli/main.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,8 @@ def init(
287287
@click.option(
288288
"--use-project-index",
289289
is_flag=True,
290-
help="Use the persistent project index to load and render only the target model and its upstream dependencies.",
290+
default=None,
291+
help="Use the persistent project index to load and render only the target model and its upstream dependencies. Can also be enabled with render.use_project_index.",
291292
)
292293
@opt.format_options
293294
@click.pass_context
@@ -302,7 +303,7 @@ def render(
302303
expand: t.Optional[t.Union[bool, t.Iterable[str]]] = None,
303304
dialect: t.Optional[str] = None,
304305
no_format: bool = False,
305-
use_project_index: bool = False,
306+
use_project_index: t.Optional[bool] = None,
306307
**format_kwargs: t.Any,
307308
) -> None:
308309
"""Render a model's query, optionally expanding referenced models."""

sqlmesh/core/config/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
from sqlmesh.core.config.naming import NameInferenceConfig as NameInferenceConfig
3838
from sqlmesh.core.config.linter import LinterConfig as LinterConfig
3939
from sqlmesh.core.config.plan import PlanConfig as PlanConfig
40+
from sqlmesh.core.config.render import RenderConfig as RenderConfig
4041
from sqlmesh.core.config.root import Config as Config, DbtConfig as DbtConfig
4142
from sqlmesh.core.config.run import RunConfig as RunConfig
4243
from sqlmesh.core.config.scheduler import BuiltInSchedulerConfig as BuiltInSchedulerConfig

sqlmesh/core/config/render.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
from __future__ import annotations
2+
3+
from sqlmesh.core.config.base import BaseConfig
4+
5+
6+
class RenderConfig(BaseConfig):
7+
"""Configuration for rendering model queries.
8+
9+
Args:
10+
use_project_index: Whether to use the persistent project index when rendering.
11+
"""
12+
13+
use_project_index: bool = False

sqlmesh/core/config/root.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
from sqlmesh.core.config.naming import NameInferenceConfig as NameInferenceConfig
3636
from sqlmesh.core.config.linter import LinterConfig as LinterConfig
3737
from sqlmesh.core.config.plan import PlanConfig
38+
from sqlmesh.core.config.render import RenderConfig
3839
from sqlmesh.core.config.run import RunConfig
3940
from sqlmesh.core.config.dbt import DbtConfig
4041
from sqlmesh.core.config.scheduler import (
@@ -141,6 +142,7 @@ class Config(BaseConfig):
141142
format: The formatting options for SQL code.
142143
ui: The UI configuration for SQLMesh.
143144
plan: The plan configuration.
145+
render: The render configuration.
144146
migration: The migration configuration.
145147
variables: A dictionary of variables that can be used in models / macros.
146148
disable_anonymized_analytics: Whether to disable the anonymized analytics collection.
@@ -183,6 +185,7 @@ class Config(BaseConfig):
183185
format: FormatConfig = FormatConfig()
184186
ui: UIConfig = UIConfig()
185187
plan: PlanConfig = PlanConfig()
188+
render: RenderConfig = RenderConfig()
186189
migration: MigrationConfig = MigrationConfig()
187190
model_naming: NameInferenceConfig = NameInferenceConfig()
188191
variables: t.Dict[str, t.Any] = {}
@@ -208,6 +211,7 @@ class Config(BaseConfig):
208211
"ui": UpdateStrategy.NESTED_UPDATE,
209212
"loader_kwargs": UpdateStrategy.KEY_UPDATE,
210213
"plan": UpdateStrategy.NESTED_UPDATE,
214+
"render": UpdateStrategy.NESTED_UPDATE,
211215
"before_all": UpdateStrategy.EXTEND,
212216
"after_all": UpdateStrategy.EXTEND,
213217
"linter": UpdateStrategy.NESTED_UPDATE,

sqlmesh/core/context.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1199,7 +1199,7 @@ def render(
11991199
end: t.Optional[TimeLike] = None,
12001200
execution_time: t.Optional[TimeLike] = None,
12011201
expand: t.Union[bool, t.Iterable[str]] = False,
1202-
use_project_index: bool = False,
1202+
use_project_index: t.Optional[bool] = None,
12031203
**kwargs: t.Any,
12041204
) -> exp.Expr:
12051205
"""Renders a model's query, expanding macros with provided kwargs, and optionally expanding referenced models.
@@ -1213,12 +1213,16 @@ def render(
12131213
If True, all referenced models are expanded as raw queries.
12141214
If a list, only referenced models are expanded as raw queries.
12151215
use_project_index: Whether to use the persistent project index to load and
1216-
render only the target model and its transitive upstream dependencies.
1216+
render only the target model and its transitive upstream dependencies. If
1217+
omitted, the value of ``render.use_project_index`` is used.
12171218
12181219
Returns:
12191220
The rendered expression.
12201221
"""
12211222
execution_time = execution_time or now()
1223+
use_project_index = (
1224+
self.config.render.use_project_index if use_project_index is None else use_project_index
1225+
)
12221226

12231227
if not self._loaded:
12241228
target_fqns = (

tests/core/test_config.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
ModelDefaultsConfig,
1717
BigQueryConnectionConfig,
1818
MotherDuckConnectionConfig,
19+
RenderConfig,
1920
BuiltInSchedulerConfig,
2021
EnvironmentSuffixTarget,
2122
TableNamingConvention,
@@ -70,6 +71,13 @@ def python_config_path(tmp_path_factory) -> Path:
7071
return config_path
7172

7273

74+
def test_render_config() -> None:
75+
config = Config.parse_obj({"render": {"use_project_index": True}})
76+
77+
assert config.render == RenderConfig(use_project_index=True)
78+
assert Config().update_with(config).render.use_project_index is True
79+
80+
7381
def test_update_with_gateways():
7482
gateway0_config = GatewayConfig(connection=DuckDBConnectionConfig())
7583
gateway1_config = GatewayConfig(connection=DuckDBConnectionConfig(database="test"))

0 commit comments

Comments
 (0)