sqlmesh 0.209.1.dev36__py3-none-any.whl → 0.209.1.dev38__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
sqlmesh/_version.py CHANGED
@@ -17,5 +17,5 @@ __version__: str
17
17
  __version_tuple__: VERSION_TUPLE
18
18
  version_tuple: VERSION_TUPLE
19
19
 
20
- __version__ = version = '0.209.1.dev36'
21
- __version_tuple__ = version_tuple = (0, 209, 1, 'dev36')
20
+ __version__ = version = '0.209.1.dev38'
21
+ __version_tuple__ = version_tuple = (0, 209, 1, 'dev38')
@@ -8,6 +8,7 @@ from sqlmesh.integrations.dlt import generate_dlt_models_and_settings
8
8
  from sqlmesh.utils.date import yesterday_ds
9
9
  from sqlmesh.utils.errors import SQLMeshError
10
10
 
11
+ from sqlmesh.core.config.common import DBT_PROJECT_FILENAME
11
12
  from sqlmesh.core.config.connection import (
12
13
  CONNECTION_CONFIG_TO_TYPE,
13
14
  DIALECT_TO_TYPE,
@@ -113,11 +114,10 @@ linter:
113
114
  - ambiguousorinvalidcolumn
114
115
  - invalidselectstarexpansion
115
116
  """,
116
- ProjectTemplate.DBT: """from pathlib import Path
117
-
118
- from sqlmesh.dbt.loader import sqlmesh_config
119
-
120
- config = sqlmesh_config(Path(__file__).parent)
117
+ ProjectTemplate.DBT: f"""# --- Model Defaults ---
118
+ # https://sqlmesh.readthedocs.io/en/stable/reference/model_configuration/#model-defaults
119
+ model_defaults:
120
+ start: {start or yesterday_ds()}
121
121
  """,
122
122
  }
123
123
 
@@ -285,8 +285,13 @@ def init_example_project(
285
285
  cli_mode: InitCliMode = InitCliMode.DEFAULT,
286
286
  ) -> Path:
287
287
  root_path = Path(path)
288
- config_extension = "py" if template == ProjectTemplate.DBT else "yaml"
289
- config_path = root_path / f"config.{config_extension}"
288
+
289
+ config_path = root_path / "config.yaml"
290
+ if template == ProjectTemplate.DBT:
291
+ # name the config file `sqlmesh.yaml` to make it clear that within the context of all
292
+ # the existing yaml files DBT project, this one specifically relates to configuring the sqlmesh engine
293
+ config_path = root_path / "sqlmesh.yaml"
294
+
290
295
  audits_path = root_path / "audits"
291
296
  macros_path = root_path / "macros"
292
297
  models_path = root_path / "models"
@@ -298,7 +303,7 @@ def init_example_project(
298
303
  f"Found an existing config file '{config_path}'.\n\nPlease change to another directory or remove the existing file."
299
304
  )
300
305
 
301
- if template == ProjectTemplate.DBT and not Path(root_path, "dbt_project.yml").exists():
306
+ if template == ProjectTemplate.DBT and not Path(root_path, DBT_PROJECT_FILENAME).exists():
302
307
  raise SQLMeshError(
303
308
  "Required dbt project file 'dbt_project.yml' not found in the current directory.\n\nPlease add it or change directories before running `sqlmesh init` to set up your project."
304
309
  )
@@ -8,6 +8,16 @@ from sqlmesh.utils import classproperty
8
8
  from sqlmesh.utils.errors import ConfigError
9
9
  from sqlmesh.utils.pydantic import field_validator
10
10
 
11
+ # Config files that can be present in the project dir
12
+ ALL_CONFIG_FILENAMES = ("config.py", "config.yml", "config.yaml", "sqlmesh.yml", "sqlmesh.yaml")
13
+
14
+ # For personal paths (~/.sqlmesh/) where python config is not supported
15
+ YAML_CONFIG_FILENAMES = tuple(n for n in ALL_CONFIG_FILENAMES if not n.endswith(".py"))
16
+
17
+ # Note: is here to prevent having to import from sqlmesh.dbt.loader which introduces a dependency
18
+ # on dbt-core in a native project
19
+ DBT_PROJECT_FILENAME = "dbt_project.yml"
20
+
11
21
 
12
22
  class EnvironmentSuffixTarget(str, Enum):
13
23
  # Intended to create virtual environments in their own schemas, with names like "<model_schema_name>__<env name>". The view name is untouched.
@@ -10,6 +10,11 @@ from dotenv import load_dotenv
10
10
  from sqlglot.helper import ensure_list
11
11
 
12
12
  from sqlmesh.core import constants as c
13
+ from sqlmesh.core.config.common import (
14
+ ALL_CONFIG_FILENAMES,
15
+ YAML_CONFIG_FILENAMES,
16
+ DBT_PROJECT_FILENAME,
17
+ )
13
18
  from sqlmesh.core.config.model import ModelDefaultsConfig
14
19
  from sqlmesh.core.config.root import Config
15
20
  from sqlmesh.utils import env_vars, merge_dicts, sys_path
@@ -51,10 +56,7 @@ def load_configs(
51
56
  return {path: config for path in absolute_paths}
52
57
 
53
58
  config_env_vars = None
54
- personal_paths = [
55
- sqlmesh_path / "config.yml",
56
- sqlmesh_path / "config.yaml",
57
- ]
59
+ personal_paths = [sqlmesh_path / name for name in YAML_CONFIG_FILENAMES]
58
60
  for path in personal_paths:
59
61
  if path.exists():
60
62
  config_env_vars = load_config_from_yaml(path).get("env_vars")
@@ -65,7 +67,7 @@ def load_configs(
65
67
  return {
66
68
  path: load_config_from_paths(
67
69
  config_type,
68
- project_paths=[path / "config.py", path / "config.yml", path / "config.yaml"],
70
+ project_paths=[path / name for name in ALL_CONFIG_FILENAMES],
69
71
  personal_paths=personal_paths,
70
72
  config_name=config,
71
73
  )
@@ -156,6 +158,22 @@ def load_config_from_paths(
156
158
  )
157
159
 
158
160
  no_dialect_err_msg = "Default model SQL dialect is a required configuration parameter. Set it in the `model_defaults` `dialect` key in your config file."
161
+
162
+ # if "dbt_project.yml" is present *and there was no python config already defined*,
163
+ # create a basic one to ensure we are using the DBT loader.
164
+ # any config within yaml files will get overlayed on top of it.
165
+ if not python_config:
166
+ potential_project_files = [f / DBT_PROJECT_FILENAME for f in visited_folders]
167
+ dbt_project_file = next((f for f in potential_project_files if f.exists()), None)
168
+ if dbt_project_file:
169
+ from sqlmesh.dbt.loader import sqlmesh_config
170
+
171
+ dbt_python_config = sqlmesh_config(project_root=dbt_project_file.parent)
172
+ if type(dbt_python_config) != config_type:
173
+ dbt_python_config = convert_config_type(dbt_python_config, config_type)
174
+
175
+ python_config = dbt_python_config
176
+
159
177
  if python_config:
160
178
  model_defaults = python_config.model_defaults
161
179
  if model_defaults.dialect is None:
@@ -165,6 +183,7 @@ def load_config_from_paths(
165
183
  model_defaults = non_python_config.model_defaults
166
184
  if model_defaults.dialect is None:
167
185
  raise ConfigError(no_dialect_err_msg)
186
+
168
187
  return non_python_config
169
188
 
170
189
 
sqlmesh/dbt/common.py CHANGED
@@ -14,10 +14,11 @@ from sqlmesh.utils.errors import ConfigError
14
14
  from sqlmesh.utils.jinja import MacroReference
15
15
  from sqlmesh.utils.pydantic import PydanticModel, field_validator
16
16
  from sqlmesh.utils.yaml import load
17
+ from sqlmesh.core.config.common import DBT_PROJECT_FILENAME
17
18
 
18
19
  T = t.TypeVar("T", bound="GeneralConfig")
19
20
 
20
- PROJECT_FILENAME = "dbt_project.yml"
21
+ PROJECT_FILENAME = DBT_PROJECT_FILENAME
21
22
 
22
23
  JINJA_ONLY = {
23
24
  "adapter",
sqlmesh/dbt/manifest.py CHANGED
@@ -32,6 +32,7 @@ except ImportError:
32
32
  from dbt.tracking import do_not_track
33
33
 
34
34
  from sqlmesh.core import constants as c
35
+ from sqlmesh.core.config import ModelDefaultsConfig
35
36
  from sqlmesh.dbt.basemodel import Dependencies
36
37
  from sqlmesh.dbt.builtin import BUILTIN_FILTERS, BUILTIN_GLOBALS, OVERRIDDEN_MACROS
37
38
  from sqlmesh.dbt.model import ModelConfig
@@ -78,12 +79,14 @@ class ManifestHelper:
78
79
  target: TargetConfig,
79
80
  variable_overrides: t.Optional[t.Dict[str, t.Any]] = None,
80
81
  cache_dir: t.Optional[str] = None,
82
+ model_defaults: t.Optional[ModelDefaultsConfig] = None,
81
83
  ):
82
84
  self.project_path = project_path
83
85
  self.profiles_path = profiles_path
84
86
  self.profile_name = profile_name
85
87
  self.target = target
86
88
  self.variable_overrides = variable_overrides or {}
89
+ self.model_defaults = model_defaults or ModelDefaultsConfig()
87
90
 
88
91
  self.__manifest: t.Optional[Manifest] = None
89
92
  self._project_name: str = ""
@@ -380,9 +383,12 @@ class ManifestHelper:
380
383
  profile = self._load_profile()
381
384
  project = self._load_project(profile)
382
385
 
383
- if not any(k in project.models for k in ("start", "+start")):
386
+ if (
387
+ not any(k in project.models for k in ("start", "+start"))
388
+ and not self.model_defaults.start
389
+ ):
384
390
  raise ConfigError(
385
- "SQLMesh's requires a start date in order to have a finite range of backfilling data. Add start to the 'models:' block in dbt_project.yml. https://sqlmesh.readthedocs.io/en/stable/integrations/dbt/#setting-model-backfill-start-dates"
391
+ "SQLMesh requires a start date in order to have a finite range of backfilling data. Add start to the 'models:' block in dbt_project.yml. https://sqlmesh.readthedocs.io/en/stable/integrations/dbt/#setting-model-backfill-start-dates"
386
392
  )
387
393
 
388
394
  runtime_config = RuntimeConfig.from_parts(project, profile, args)
sqlmesh/dbt/model.py CHANGED
@@ -569,7 +569,7 @@ class ModelConfig(BaseModelConfig):
569
569
  query,
570
570
  dialect=model_dialect,
571
571
  kind=kind,
572
- start=self.start,
572
+ start=self.start or context.sqlmesh_config.model_defaults.start,
573
573
  audit_definitions=audit_definitions,
574
574
  path=model_kwargs.pop("path", self.path),
575
575
  # This ensures that we bypass query rendering that would otherwise be required to extract additional
sqlmesh/dbt/project.py CHANGED
@@ -76,6 +76,7 @@ class Project:
76
76
  target=profile.target,
77
77
  variable_overrides=variable_overrides,
78
78
  cache_dir=context.sqlmesh_config.cache_dir,
79
+ model_defaults=context.sqlmesh_config.model_defaults,
79
80
  )
80
81
 
81
82
  extra_fields = profile.target.extra
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sqlmesh
3
- Version: 0.209.1.dev36
3
+ Version: 0.209.1.dev38
4
4
  Summary: Next-generation data transformation framework
5
5
  Author-email: "TobikoData Inc." <engineering@tobikodata.com>
6
6
  License: Apache License
@@ -1,5 +1,5 @@
1
1
  sqlmesh/__init__.py,sha256=QjwaamJIdW7voXoS880yAx7tHm-Im4_mqGA-XJgafos,7631
2
- sqlmesh/_version.py,sha256=naVObbCL61RZL0IHMc_iqfpFzjLQrDtVY-Vul76FNhg,530
2
+ sqlmesh/_version.py,sha256=7ULrBV5pTtSKKUtK5YiPgFIuJjDOvqy8h83VzNJ6XJc,530
3
3
  sqlmesh/magics.py,sha256=xLh3u4eqpVrKRVN5KF3X84RPRqjygAB9AJP1TXwH8hg,42086
4
4
  sqlmesh/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
5
  sqlmesh/cicd/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -8,7 +8,7 @@ sqlmesh/cicd/config.py,sha256=mpgkisSBBovlNrNZir2unT8Wes6b38RW2UsU_o4e8vY,109
8
8
  sqlmesh/cli/__init__.py,sha256=MAXAyO7isbyM-PaSdFjkJNcjn32WjOl0XzxT5gvp_vo,1690
9
9
  sqlmesh/cli/main.py,sha256=xRpcd3A5aO3mX3texhvdEA2wZFYyCitWceSeUc3vo_U,36668
10
10
  sqlmesh/cli/options.py,sha256=8qEGWivk4urGikpEmaU9T8WsyaZtjCpmW4Ed25iQ73I,2543
11
- sqlmesh/cli/project_init.py,sha256=5JmDmUK0WJs39hM-p76uzHYdo1Hnx6fKuJg_pR3Hn5A,16419
11
+ sqlmesh/cli/project_init.py,sha256=arYGuPl8UKBl-SiaLidLyLDCQJYLjJVcspe7WrjCUss,16734
12
12
  sqlmesh/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
13
13
  sqlmesh/core/_typing.py,sha256=e1f7xO2aZCy38M_3VoDy-XI3shyd99-IFctgIFSgXWM,497
14
14
  sqlmesh/core/console.py,sha256=KbIXoxt5hpDENEolY-DpBlPmcWtJ9vzEgF52mjG2jPE,165710
@@ -40,14 +40,14 @@ sqlmesh/core/audit/definition.py,sha256=iPpGEOwFIXFHQFQGMyapCm7jnlotwMa-gNaCgTwz
40
40
  sqlmesh/core/config/__init__.py,sha256=5zxTXjUMuxBj4XlX6bmpIWTp4GsZY5rIdKSCTYbxRBM,2070
41
41
  sqlmesh/core/config/base.py,sha256=t8NQmsgQoZSc-k0dlDiCb8t1jj0AMYdGZ-6se9q_Pks,4898
42
42
  sqlmesh/core/config/categorizer.py,sha256=6vzUoNLjR6GOEb_2mYVz2TwmMv2BfldgHX2u-Le5HZs,1975
43
- sqlmesh/core/config/common.py,sha256=Zg0f3-iEfSE4FcJOlSQzbG8gL6CpKpFLCe8dJJgBmJs,5931
43
+ sqlmesh/core/config/common.py,sha256=9V6PltBAjYeWLOU5dAbqL55BSFfpg8z8t2Op1x_PLhU,6418
44
44
  sqlmesh/core/config/connection.py,sha256=X1MkT4hp0XOJ9EwHZ9e_sFOgN3cmNVva4Uibykx7NlQ,88271
45
45
  sqlmesh/core/config/feature_flag.py,sha256=JRcD31OG_t2cYc24meKbHDGB0iVID0P07V2oOeB_mgA,203
46
46
  sqlmesh/core/config/format.py,sha256=6CXFbvnor56xbldKE-Vrm9k_ABRoY4v6vgIb3mCihiQ,1355
47
47
  sqlmesh/core/config/gateway.py,sha256=tYngyqwd_4Qr9lhcv2hlvLvb_2pgYYtKu6hdGsTr-4I,1931
48
48
  sqlmesh/core/config/janitor.py,sha256=NP0i51V8XwMrHw8uuwQknivuudIleNiFBtBnMuXmfIY,362
49
49
  sqlmesh/core/config/linter.py,sha256=4Fh6UgY5FrRD9tk_R41Y-M_r91Wh7EQW3Pc1IdRN9Cg,1287
50
- sqlmesh/core/config/loader.py,sha256=Cml5ei1Y1SVeXu4Q47Yu3JWeV7vy6Pu8_5i7DeU0scs,8560
50
+ sqlmesh/core/config/loader.py,sha256=KgqWW8elF7SSp0eLsQYK_iSOI8QqSUIvnO4Sx7zG5Ko,9426
51
51
  sqlmesh/core/config/migration.py,sha256=3lZIlmIcQH3_hIEm3Y3jFtvpw0YXzRzAnk4OdiklO6M,408
52
52
  sqlmesh/core/config/model.py,sha256=xDKIHD8WIzsPu7DfpybPM3bLobppttCZjvD3TTVnwps,4182
53
53
  sqlmesh/core/config/naming.py,sha256=KVGaxUgswoQajXR_cHFJvgkmEFcU1V182GkOH1SJxuE,326
@@ -129,14 +129,14 @@ sqlmesh/dbt/adapter.py,sha256=WPR8EQimP4Yrra_lQmqGKUTUcA8zTYDtK6oH_i_kGI8,18006
129
129
  sqlmesh/dbt/basemodel.py,sha256=YmrgE53nrRdo4kCFkuivOPRnqhmAnQ1_XVqxYjGmNRI,12731
130
130
  sqlmesh/dbt/builtin.py,sha256=p4E1rmSLM0B5PHcFWA9J7FwScR90pIPqiMN8G4M3sBM,15173
131
131
  sqlmesh/dbt/column.py,sha256=Kvj_N3D_QegcoNQG7VqRiqy-FRfupud-6ilhlykBOgE,1873
132
- sqlmesh/dbt/common.py,sha256=g4PAL-sEdlnfb_zT-WW3xh-oamyCUoK8dUiDEMVwDWI,7804
132
+ sqlmesh/dbt/common.py,sha256=cU5u3_dYXyN2U--YEb1ev7WLfKTJMt_oGQRvsHFu1HE,7867
133
133
  sqlmesh/dbt/context.py,sha256=dxClM-G1IeMbP0v5yxC_va8QNU-uKghW2dBlSZHJOk0,10331
134
134
  sqlmesh/dbt/loader.py,sha256=Loc-yNHop-Gop80tDhziTPJwOQ01jlW6CcAV1vFsS_Q,15702
135
- sqlmesh/dbt/manifest.py,sha256=jlafUYdoG7gS2pzvJrt9JfC2afbAMORhBbBUaLl-ZTM,24894
136
- sqlmesh/dbt/model.py,sha256=eAkTnj0nh7huBFXGAO8ckr5chvdAFrqbw-gOs6uZ_NE,26015
135
+ sqlmesh/dbt/manifest.py,sha256=olX7nLmT0S6DB18cNSbo8Sr1L4n0LYgq6NLclNt5A9E,25148
136
+ sqlmesh/dbt/model.py,sha256=j5DPey2z1J8YL5Hzmt_2OMGnjfDK6YXuUQcLQ07ls_Y,26062
137
137
  sqlmesh/dbt/package.py,sha256=IBBQueVB4_4C9tIk0-GUL-O2uibNxXu6W2a4AeHHcOU,4322
138
138
  sqlmesh/dbt/profile.py,sha256=Fz2c0dJNN0xBgYEogCIKBTByjNvlA2BVBzOLQCfdEfM,3788
139
- sqlmesh/dbt/project.py,sha256=a21czHhdcm2J80Zllj2q6VvH-W_rDtlXHa8wmvHaLTo,4036
139
+ sqlmesh/dbt/project.py,sha256=bXW2VL0023mhOr0GRAcYsomIcR3qTpflWgZO3oMwtOE,4102
140
140
  sqlmesh/dbt/relation.py,sha256=rgDJQUuENjqq7kpMJJ6AdlgwYmcYjA1oFj6LCYCS-Hg,227
141
141
  sqlmesh/dbt/seed.py,sha256=UuPUTXpj3nL3JxX1fAReS263zPo31Hmj8dfOctF1oh8,4484
142
142
  sqlmesh/dbt/source.py,sha256=IZK-aOV-KdWIOPuXqRjJZAZ7phW1HUXoHtE-3clgkx4,4125
@@ -292,11 +292,11 @@ sqlmesh/utils/pydantic.py,sha256=o_NsXbIpDqNpUA1Uc5xF0ZzoXQYYB0DfHwdRxBwXPNk,120
292
292
  sqlmesh/utils/rich.py,sha256=cwQ5nJ6sgz64xHtoh6_ec7ReV5YpsOGhMtUJnwoRfEI,3549
293
293
  sqlmesh/utils/windows.py,sha256=r7Yin4WEwbvH7sKA3hOJtRsclmscNuBeCklCfVPvtQs,611
294
294
  sqlmesh/utils/yaml.py,sha256=hvo5lmybYLcIx4p6CQwufS8X4MbwS60lEBnCmYJCXmU,2336
295
- sqlmesh-0.209.1.dev36.dist-info/licenses/LICENSE,sha256=OlMefUjgWJdULtf84BLW0AZZcY8DwdgQqb_1j2862j8,11346
295
+ sqlmesh-0.209.1.dev38.dist-info/licenses/LICENSE,sha256=OlMefUjgWJdULtf84BLW0AZZcY8DwdgQqb_1j2862j8,11346
296
296
  sqlmesh_dbt/__init__.py,sha256=awYS5y5mz-1NUmx6i5h5NSTJ7tidRl9NC0FAnFWSF6U,350
297
297
  sqlmesh_dbt/cli.py,sha256=Ekn77WLMmyyr31aoDoWrZp5DS0rfiddy7pNohBK8G0s,2115
298
298
  sqlmesh_dbt/console.py,sha256=1B0B5_R1DlrEkyWVDl8G78-B6_K-ZtLPsQEhqPCfLEU,188
299
- sqlmesh_dbt/operations.py,sha256=u8O5mrbX942y6lGBHMg1GPIJLTWVOUiVw35uG3okjKg,5461
299
+ sqlmesh_dbt/operations.py,sha256=84SKp9irWLR-xYJhy7ldxixTcokdjk2WPxdQA6FDcSU,4418
300
300
  web/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
301
301
  web/client/dist/index.html,sha256=SXykdSRNgrT1k6I2dPZPEfpxPjIsi8-yVFijt-naSA4,5472
302
302
  web/client/dist/assets/Audits-Jm353fhk.js,sha256=ry6b5IKT3hLAfD5C3T2BqxulfauEV0n0YZ2vsP4eQ_U,1041
@@ -414,8 +414,8 @@ web/server/api/endpoints/models.py,sha256=kwj0s7uve3iZSMfmjkoPVMFMeY1sD0peTeyrWf
414
414
  web/server/api/endpoints/modules.py,sha256=8hqqgonGay_mJmpCw0IdbjsPhWlQH2VLdKAqha-myac,468
415
415
  web/server/api/endpoints/plan.py,sha256=bbbY50W_2MsZSTxOHWMKz0tbIm75nsRSlPy8GI2fg9Q,9306
416
416
  web/server/api/endpoints/table_diff.py,sha256=SCy3-pr5x6bEEiOaZGCDbiHQhpgxwmnz3Acqa2Ie6jI,2090
417
- sqlmesh-0.209.1.dev36.dist-info/METADATA,sha256=GlXpToVp1WAKXGlo1666Yn7gufp-V9RpIIlEK22cLfM,26686
418
- sqlmesh-0.209.1.dev36.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
419
- sqlmesh-0.209.1.dev36.dist-info/entry_points.txt,sha256=sHAf6tQczIM8xZoduN4qaUjV7QEPVUUW_LCT8EDUMv4,155
420
- sqlmesh-0.209.1.dev36.dist-info/top_level.txt,sha256=RQ-33FPe2IgL0rgossAfJkCRtqslz9b7wFARqiWLC5Q,24
421
- sqlmesh-0.209.1.dev36.dist-info/RECORD,,
417
+ sqlmesh-0.209.1.dev38.dist-info/METADATA,sha256=bWpl9zD3sw-8m8Dc56ANd9Ygvz343rNUrMIeDIsgv60,26686
418
+ sqlmesh-0.209.1.dev38.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
419
+ sqlmesh-0.209.1.dev38.dist-info/entry_points.txt,sha256=sHAf6tQczIM8xZoduN4qaUjV7QEPVUUW_LCT8EDUMv4,155
420
+ sqlmesh-0.209.1.dev38.dist-info/top_level.txt,sha256=RQ-33FPe2IgL0rgossAfJkCRtqslz9b7wFARqiWLC5Q,24
421
+ sqlmesh-0.209.1.dev38.dist-info/RECORD,,
sqlmesh_dbt/operations.py CHANGED
@@ -61,7 +61,7 @@ def create(
61
61
 
62
62
  from sqlmesh import configure_logging
63
63
  from sqlmesh.core.context import Context
64
- from sqlmesh.dbt.loader import sqlmesh_config, DbtLoader
64
+ from sqlmesh.dbt.loader import DbtLoader
65
65
  from sqlmesh.core.console import set_console
66
66
  from sqlmesh_dbt.console import DbtCliConsole
67
67
  from sqlmesh.utils.errors import SQLMeshError
@@ -71,34 +71,14 @@ def create(
71
71
 
72
72
  progress.update(load_task_id, description="Loading project", total=None)
73
73
 
74
- # inject default start date if one is not specified to prevent the user from having to do anything
75
- _inject_default_start_date(project_dir)
76
-
77
- config = sqlmesh_config(
78
- project_root=project_dir,
79
- # do we want to use a local duckdb for state?
80
- # warehouse state has a bunch of overhead to initialize, is slow for ongoing operations and will create tables that perhaps the user was not expecting
81
- # on the other hand, local state is not portable
82
- state_connection=None,
83
- )
74
+ project_dir = project_dir or Path.cwd()
75
+ init_project_if_required(project_dir)
84
76
 
85
77
  sqlmesh_context = Context(
86
- config=config,
78
+ paths=[project_dir],
87
79
  load=True,
88
80
  )
89
81
 
90
- # this helps things which want a default project-level start date, like the "effective from date" for forward-only plans
91
- if not sqlmesh_context.config.model_defaults.start:
92
- min_start_date = min(
93
- (
94
- model.start
95
- for model in sqlmesh_context.models.values()
96
- if model.start is not None
97
- ),
98
- default=None,
99
- )
100
- sqlmesh_context.config.model_defaults.start = min_start_date
101
-
102
82
  dbt_loader = sqlmesh_context._loaders[0]
103
83
  if not isinstance(dbt_loader, DbtLoader):
104
84
  raise SQLMeshError(f"Unexpected loader type: {type(dbt_loader)}")
@@ -109,25 +89,20 @@ def create(
109
89
  return DbtOperations(sqlmesh_context, dbt_project)
110
90
 
111
91
 
112
- def _inject_default_start_date(project_dir: t.Optional[Path] = None) -> None:
92
+ def init_project_if_required(project_dir: Path) -> None:
113
93
  """
114
- SQLMesh needs a start date to as the starting point for calculating intervals on incremental models
94
+ SQLMesh needs a start date to as the starting point for calculating intervals on incremental models, amongst other things
115
95
 
116
96
  Rather than forcing the user to update their config manually or having a default that is not saved between runs,
117
- we can inject it automatically to the dbt_project.yml file
97
+ we can generate a basic SQLMesh config if it doesnt exist.
98
+
99
+ This is preferable to trying to inject config into `dbt_project.yml` because it means we have full control over the file
100
+ and dont need to worry about accidentally reformatting it or accidentally clobbering other config
118
101
  """
119
- from sqlmesh.dbt.project import PROJECT_FILENAME, load_yaml
120
- from sqlmesh.utils.yaml import dump
121
- from sqlmesh.utils.date import yesterday_ds
122
-
123
- project_yaml_path = (project_dir or Path.cwd()) / PROJECT_FILENAME
124
- if project_yaml_path.exists():
125
- loaded_project_file = load_yaml(project_yaml_path)
126
- start_date_keys = ("start", "+start")
127
- if "models" in loaded_project_file and all(
128
- k not in loaded_project_file["models"] for k in start_date_keys
129
- ):
130
- loaded_project_file["models"]["+start"] = yesterday_ds()
131
- # todo: this may format the file differently, is that acceptable?
132
- with project_yaml_path.open("w") as f:
133
- dump(loaded_project_file, f)
102
+ from sqlmesh.cli.project_init import init_example_project, ProjectTemplate
103
+ from sqlmesh.core.config.common import ALL_CONFIG_FILENAMES
104
+ from sqlmesh.core.console import get_console
105
+
106
+ if not any(f.exists() for f in [project_dir / file for file in ALL_CONFIG_FILENAMES]):
107
+ get_console().log_warning("No existing SQLMesh config detected; creating one")
108
+ init_example_project(path=project_dir, engine_type=None, template=ProjectTemplate.DBT)