Skip to content

Commit ab004c1

Browse files
authored
Feat: Introduce pinned environments which are omitted by the janitor process (#1043)
1 parent 5648c9e commit ab004c1

File tree

4 files changed

+20
-7
lines changed

4 files changed

+20
-7
lines changed

docs/reference/configuration.md

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -144,13 +144,14 @@ See [Airflow Integration Guide](../integrations/airflow.md) for information on h
144144
| `default_gateway` | The name of a gateway to use if one is not provided explicitly (Default: the gateway defined first in the `gateways` option) | string | N |
145145

146146
## SQLMesh-specific configurations
147-
| Option | Description | Type | Required |
147+
| Option | Description | Type | Required |
148148
|---------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:--------------------:|:--------:|
149-
| `snapshot_ttl` | The period of time that a model snapshot not a part of any environment should exist before being deleted. This is defined as a string with the default `in 1 week`. Other [relative dates](https://dateparser.readthedocs.io/en/latest/) can be used, such as `in 30 days`. (Default: `in 1 week`) | string | N |
150-
| `environment_ttl` | The period of time that a development environment should exist before being deleted. This is defined as a string with the default `in 1 week`. Other [relative dates](https://dateparser.readthedocs.io/en/latest/) can be used, such as `in 30 days`. (Default: `in 1 week`) | string | N |
151-
| `ignore_patterns` | Files that match glob patterns specified in this list are ignored when scanning the project folder (Default: `[]`) | list[string] | N |
152-
| `time_column_format` | The default format to use for all model time columns. This time format uses [python format codes](https://docs.python.org/3/library/datetime.html#strftime-and-strptime-format-codes) (Default: `%Y-%m-%d`) | string | N |
153-
| `auto_categorize_changes` | Indicates whether SQLMesh should attempt to automatically [categorize](../concepts/plans.md#change-categories) model changes during plan creation per each model source type ([Additional Details](#auto-categorize-changes)) | dict[string, string] | N |
149+
| `snapshot_ttl` | The period of time that a model snapshot not a part of any environment should exist before being deleted. This is defined as a string with the default `in 1 week`. Other [relative dates](https://dateparser.readthedocs.io/en/latest/) can be used, such as `in 30 days`. (Default: `in 1 week`) | string | N |
150+
| `environment_ttl` | The period of time that a development environment should exist before being deleted. This is defined as a string with the default `in 1 week`. Other [relative dates](https://dateparser.readthedocs.io/en/latest/) can be used, such as `in 30 days`. (Default: `in 1 week`) | string | N |
151+
| `pinned_environments` | The list of development environments that are exempt from deletion due to expiration | list[string] | N |
152+
| `ignore_patterns` | Files that match glob patterns specified in this list are ignored when scanning the project folder (Default: `[]`) | list[string] | N |
153+
| `time_column_format` | The default format to use for all model time columns. This time format uses [python format codes](https://docs.python.org/3/library/datetime.html#strftime-and-strptime-format-codes) (Default: `%Y-%m-%d`) | string | N |
154+
| `auto_categorize_changes` | Indicates whether SQLMesh should attempt to automatically [categorize](../concepts/plans.md#change-categories) model changes during plan creation per each model source type ([Additional Details](#auto-categorize-changes)) | dict[string, string] | N |
154155

155156
## Model configuration
156157
This section contains options that are specific to models, which are set automatically unless explicitly overridden in the model definition.

sqlmesh/core/config/root.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ class Config(BaseConfig):
3737
auto_categorize_changes: Indicates whether SQLMesh should attempt to automatically categorize model changes (breaking / non-breaking)
3838
during plan creation.
3939
users: A list of users that can be used for approvals/notifications.
40+
pinned_environments: A list of development environment names that should not be deleted by the janitor task.
4041
model_defaults: Default values for model definitions.
4142
"""
4243

@@ -54,6 +55,7 @@ class Config(BaseConfig):
5455
auto_categorize_changes: CategorizerConfig = CategorizerConfig()
5556
users: t.List[User] = []
5657
model_defaults: ModelDefaultsConfig = ModelDefaultsConfig()
58+
pinned_environments: t.Set[str] = set()
5759
loader: t.Type[Loader] = SqlMeshLoader
5860
env_vars: t.Dict[str, str] = {}
5961

@@ -64,6 +66,7 @@ class Config(BaseConfig):
6466
"users": UpdateStrategy.EXTEND,
6567
"model_defaults": UpdateStrategy.NESTED_UPDATE,
6668
"auto_categorize_changes": UpdateStrategy.NESTED_UPDATE,
69+
"pinned_environments": UpdateStrategy.EXTEND,
6770
}
6871

6972
@validator("gateways", always=True)

sqlmesh/core/context.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,7 @@ def __init__(
233233
self.gateway = gateway
234234
self._scheduler = self.config.get_scheduler(self.gateway)
235235
self.environment_ttl = self.config.environment_ttl
236+
self.pinned_environments = Environment.normalize_names(self.config.pinned_environments)
236237
self.auto_categorize_changes = self.config.auto_categorize_changes
237238

238239
connection_config = self.config.get_connection(self.gateway)
@@ -695,6 +696,10 @@ def plan(
695696

696697
self._run_plan_tests(skip_tests=skip_tests)
697698

699+
environment_ttl = (
700+
self.environment_ttl if environment not in self.pinned_environments else None
701+
)
702+
698703
plan = Plan(
699704
context_diff=self._context_diff(environment or c.PROD, create_from=create_from),
700705
state_reader=self.state_reader,
@@ -707,7 +712,7 @@ def plan(
707712
skip_backfill=skip_backfill,
708713
is_dev=environment != c.PROD,
709714
forward_only=forward_only,
710-
environment_ttl=self.environment_ttl,
715+
environment_ttl=environment_ttl,
711716
categorizer_config=self.auto_categorize_changes,
712717
auto_categorization_enabled=not no_auto_categorization,
713718
effective_from=effective_from,

sqlmesh/core/environment.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,3 +59,7 @@ def normalize_name(cls, v: str | Environment) -> str | Environment:
5959
if not isinstance(v, str):
6060
raise TypeError(f"Expected str or Environment, got {type(v).__name__}")
6161
return cls._normalize_name(v)
62+
63+
@classmethod
64+
def normalize_names(cls, values: t.Iterable[str]) -> t.Set[str]:
65+
return {cls.normalize_name(value) for value in values}

0 commit comments

Comments
 (0)