Skip to content

Commit 74fdcb6

Browse files
authored
Introduce config env_vars (#1047)
1 parent f07bb06 commit 74fdcb6

5 files changed

Lines changed: 43 additions & 14 deletions

File tree

sqlmesh/core/config/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
SparkConnectionConfig,
1111
)
1212
from sqlmesh.core.config.gateway import GatewayConfig
13-
from sqlmesh.core.config.loader import load_config_from_paths
13+
from sqlmesh.core.config.loader import load_config_from_paths, load_config_from_yaml
1414
from sqlmesh.core.config.model import ModelDefaultsConfig
1515
from sqlmesh.core.config.root import Config
1616
from sqlmesh.core.config.scheduler import AirflowSchedulerConfig, BuiltInSchedulerConfig

sqlmesh/core/config/loader.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,10 @@
1313

1414

1515
def load_config_from_paths(
16-
*paths: Path, config_name: str = "config", load_from_env: bool = True
16+
*paths: Path,
17+
config_name: str = "config",
18+
load_from_env: bool = True,
19+
config_defaults: Config | None = None,
1720
) -> Config:
1821
config: t.Optional[Config] = None
1922

@@ -34,7 +37,7 @@ def load_config_from_paths(
3437
if extension in ("yml", "yaml"):
3538
if config_name != "config":
3639
raise ConfigError(
37-
f"YAML configs do not support multiple configs. Use Python instead."
40+
"YAML configs do not support multiple configs. Use Python instead."
3841
)
3942
next_config = load_config_from_yaml(path)
4043
elif extension == "py":
@@ -54,6 +57,9 @@ def load_config_from_paths(
5457
if load_from_env:
5558
config = config.update_with(load_config_from_env())
5659

60+
if config_defaults:
61+
config = config_defaults.update_with(config)
62+
5763
return config
5864

5965

sqlmesh/core/config/root.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ class Config(BaseConfig):
5555
users: t.List[User] = []
5656
model_defaults: ModelDefaultsConfig = ModelDefaultsConfig()
5757
loader: t.Type[Loader] = SqlMeshLoader
58+
env_vars: t.Dict[str, str] = {}
5859

5960
_FIELD_UPDATE_STRATEGY: t.ClassVar[t.Dict[str, UpdateStrategy]] = {
6061
"gateways": UpdateStrategy.KEY_UPDATE,

sqlmesh/core/context.py

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@
4747
from sqlmesh.core import constants as c
4848
from sqlmesh.core._typing import NotificationTarget
4949
from sqlmesh.core.audit import Audit
50-
from sqlmesh.core.config import Config, load_config_from_paths
50+
from sqlmesh.core.config import Config, load_config_from_paths, load_config_from_yaml
5151
from sqlmesh.core.console import Console, get_console
5252
from sqlmesh.core.context_diff import ContextDiff
5353
from sqlmesh.core.dialect import (
@@ -75,7 +75,7 @@
7575
from sqlmesh.core.table_diff import TableDiff
7676
from sqlmesh.core.test import get_all_model_tests, run_model_tests, run_tests
7777
from sqlmesh.core.user import User
78-
from sqlmesh.utils import UniqueKeyDict, sys_path
78+
from sqlmesh.utils import UniqueKeyDict, env_vars, sys_path
7979
from sqlmesh.utils.dag import DAG
8080
from sqlmesh.utils.date import TimeLike, yesterday_ds
8181
from sqlmesh.utils.errors import (
@@ -1082,15 +1082,23 @@ def _load_configs(
10821082
if isinstance(config, Config):
10831083
return {path: config for path in paths}
10841084

1085-
lookup_paths = [self.sqlmesh_path / "config.yml", self.sqlmesh_path / "config.yaml"]
1086-
1087-
return {
1088-
path: load_config_from_paths(
1089-
*(lookup_paths + [path / "config.py", path / "config.yml", path / "config.yaml"]),
1090-
config_name=config,
1091-
)
1092-
for path in paths
1093-
}
1085+
config_defaults = None
1086+
for path in (self.sqlmesh_path / "config.yml", self.sqlmesh_path / "config.yaml"):
1087+
if path.exists():
1088+
config_defaults = load_config_from_yaml(path)
1089+
break
1090+
1091+
with env_vars(config_defaults.env_vars if config_defaults else {}):
1092+
return {
1093+
path: load_config_from_paths(
1094+
path / "config.py",
1095+
path / "config.yml",
1096+
path / "config.yaml",
1097+
config_name=config,
1098+
config_defaults=config_defaults,
1099+
)
1100+
for path in paths
1101+
}
10941102

10951103
def _run_janitor(self) -> None:
10961104
expired_environments = self.state_sync.delete_expired_environments()

sqlmesh/utils/__init__.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from __future__ import annotations
22

33
import importlib
4+
import os
45
import re
56
import sys
67
import time
@@ -218,3 +219,16 @@ class classproperty(property):
218219

219220
def __get__(self, obj: t.Any, owner: t.Any = None) -> t.Any:
220221
return classmethod(self.fget).__get__(None, owner)() # type: ignore
222+
223+
224+
@contextmanager
225+
def env_vars(environ: dict[str, str]) -> t.Iterator[None]:
226+
"""A context manager to temporarily modify environment variables."""
227+
old_environ = os.environ.copy()
228+
os.environ.update(environ)
229+
230+
try:
231+
yield
232+
finally:
233+
os.environ.clear()
234+
os.environ.update(old_environ)

0 commit comments

Comments
 (0)