Skip to content

Commit 98b2d25

Browse files
committed
chore: make path optional
- more correctly represent path being optional
1 parent 3b66046 commit 98b2d25

File tree

17 files changed

+98
-50
lines changed

17 files changed

+98
-50
lines changed

sqlmesh/core/context.py

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -942,10 +942,15 @@ def config_for_path(self, path: Path) -> t.Tuple[Config, Path]:
942942

943943
def config_for_node(self, node: str | Model | Audit) -> Config:
944944
if isinstance(node, str):
945-
return self.config_for_path(self.get_snapshot(node, raise_if_missing=True).node._path)[
946-
0
947-
] # type: ignore
948-
return self.config_for_path(node._path)[0] # type: ignore
945+
path = self.get_snapshot(node, raise_if_missing=True).node._path
946+
if path is None:
947+
return self.config
948+
config = self.config_for_path(path)
949+
return config[0]
950+
path = node._path
951+
if path is None:
952+
return self.config
953+
return self.config_for_path(path)[0] # type: ignore
949954

950955
@property
951956
def models(self) -> MappingProxyType[str, Model]:

sqlmesh/core/macros.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ def __init__(
171171
resolve_tables: t.Optional[t.Callable[[exp.Expression], exp.Expression]] = None,
172172
snapshots: t.Optional[t.Dict[str, Snapshot]] = None,
173173
default_catalog: t.Optional[str] = None,
174-
path: Path = Path(),
174+
path: t.Optional[Path] = None,
175175
environment_naming_info: t.Optional[EnvironmentNamingInfo] = None,
176176
model_fqn: t.Optional[str] = None,
177177
):
@@ -1384,7 +1384,7 @@ def normalize_macro_name(name: str) -> str:
13841384
def call_macro(
13851385
func: t.Callable,
13861386
dialect: DialectType,
1387-
path: Path,
1387+
path: t.Optional[Path],
13881388
provided_args: t.Tuple[t.Any, ...],
13891389
provided_kwargs: t.Dict[str, t.Any],
13901390
**optional_kwargs: t.Any,
@@ -1431,7 +1431,7 @@ def _coerce(
14311431
expr: t.Any,
14321432
typ: t.Any,
14331433
dialect: DialectType,
1434-
path: Path,
1434+
path: t.Optional[Path] = None,
14351435
strict: bool = False,
14361436
) -> t.Any:
14371437
"""Coerces the given expression to the specified type on a best-effort basis."""

sqlmesh/core/model/definition.py

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1646,6 +1646,8 @@ def is_seed(self) -> bool:
16461646
def seed_path(self) -> Path:
16471647
seed_path = Path(self.kind.path)
16481648
if not seed_path.is_absolute():
1649+
if self._path is None:
1650+
raise SQLMeshError(f"Seed model '{self.name}' has no path")
16491651
return self._path.parent / seed_path
16501652
return seed_path
16511653

@@ -2020,7 +2022,7 @@ def load_sql_based_model(
20202022
expressions: t.List[exp.Expression],
20212023
*,
20222024
defaults: t.Optional[t.Dict[str, t.Any]] = None,
2023-
path: Path = Path(),
2025+
path: t.Optional[Path] = None,
20242026
module_path: Path = Path(),
20252027
time_column_format: str = c.DEFAULT_TIME_COLUMN_FORMAT,
20262028
macros: t.Optional[MacroRegistry] = None,
@@ -2171,6 +2173,8 @@ def load_sql_based_model(
21712173
# The name of the model will be inferred from its path relative to `models/`, if it's not explicitly specified
21722174
name = meta_fields.pop("name", "")
21732175
if not name and infer_names:
2176+
if path is None:
2177+
raise ValueError("Model must have a name", path)
21742178
name = get_model_name(path)
21752179

21762180
if not name:
@@ -2249,7 +2253,7 @@ def create_seed_model(
22492253
name: TableName,
22502254
seed_kind: SeedKind,
22512255
*,
2252-
path: Path = Path(),
2256+
path: t.Optional[Path] = None,
22532257
module_path: Path = Path(),
22542258
**kwargs: t.Any,
22552259
) -> Model:
@@ -2268,7 +2272,12 @@ def create_seed_model(
22682272
seed_path = module_path.joinpath(*subdirs)
22692273
seed_kind.path = str(seed_path)
22702274
elif not seed_path.is_absolute():
2271-
seed_path = path / seed_path if path.is_dir() else path.parent / seed_path
2275+
if path is None:
2276+
seed_path = seed_path
2277+
elif path.is_dir():
2278+
seed_path = path / seed_path
2279+
else:
2280+
seed_path = path.parent / seed_path
22722281

22732282
seed = create_seed(seed_path)
22742283

@@ -2403,7 +2412,7 @@ def _create_model(
24032412
name: TableName,
24042413
*,
24052414
defaults: t.Optional[t.Dict[str, t.Any]] = None,
2406-
path: Path = Path(),
2415+
path: t.Optional[Path] = None,
24072416
time_column_format: str = c.DEFAULT_TIME_COLUMN_FORMAT,
24082417
jinja_macros: t.Optional[JinjaMacroRegistry] = None,
24092418
jinja_macro_references: t.Optional[t.Set[MacroReference]] = None,
@@ -2588,7 +2597,7 @@ def _create_model(
25882597

25892598
def _split_sql_model_statements(
25902599
expressions: t.List[exp.Expression],
2591-
path: Path,
2600+
path: t.Optional[Path],
25922601
dialect: t.Optional[str] = None,
25932602
) -> t.Tuple[
25942603
t.Optional[exp.Expression],
@@ -2709,7 +2718,7 @@ def _refs_to_sql(values: t.Any) -> exp.Expression:
27092718
def render_meta_fields(
27102719
fields: t.Dict[str, t.Any],
27112720
module_path: Path,
2712-
path: Path,
2721+
path: t.Optional[Path],
27132722
jinja_macros: t.Optional[JinjaMacroRegistry],
27142723
macros: t.Optional[MacroRegistry],
27152724
dialect: DialectType,
@@ -2793,7 +2802,7 @@ def render_field_value(value: t.Any) -> t.Any:
27932802
def render_model_defaults(
27942803
defaults: t.Dict[str, t.Any],
27952804
module_path: Path,
2796-
path: Path,
2805+
path: t.Optional[Path],
27972806
jinja_macros: t.Optional[JinjaMacroRegistry],
27982807
macros: t.Optional[MacroRegistry],
27992808
dialect: DialectType,
@@ -2843,7 +2852,7 @@ def parse_defaults_properties(
28432852
def render_expression(
28442853
expression: exp.Expression,
28452854
module_path: Path,
2846-
path: Path,
2855+
path: t.Optional[Path],
28472856
jinja_macros: t.Optional[JinjaMacroRegistry] = None,
28482857
macros: t.Optional[MacroRegistry] = None,
28492858
dialect: DialectType = None,

sqlmesh/core/node.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ class _Node(PydanticModel):
199199
interval_unit_: t.Optional[IntervalUnit] = Field(alias="interval_unit", default=None)
200200
tags: t.List[str] = []
201201
stamp: t.Optional[str] = None
202-
_path: Path = Path()
202+
_path: t.Optional[Path] = None
203203
_data_hash: t.Optional[str] = None
204204
_metadata_hash: t.Optional[str] = None
205205

sqlmesh/core/renderer.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ def __init__(
4343
expression: exp.Expression,
4444
dialect: DialectType,
4545
macro_definitions: t.List[d.MacroDef],
46-
path: Path = Path(),
46+
path: t.Optional[Path] = None,
4747
jinja_macro_registry: t.Optional[JinjaMacroRegistry] = None,
4848
python_env: t.Optional[t.Dict[str, Executable]] = None,
4949
only_execution_time: bool = False,

sqlmesh/core/snapshot/definition.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2198,7 +2198,7 @@ def check_ready_intervals(
21982198
context: ExecutionContext,
21992199
python_env: t.Dict[str, Executable],
22002200
dialect: DialectType = None,
2201-
path: Path = Path(),
2201+
path: t.Optional[Path] = None,
22022202
kwargs: t.Optional[t.Dict] = None,
22032203
) -> Intervals:
22042204
checked_intervals: Intervals = []

sqlmesh/dbt/converter/convert.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,8 @@ def _convert_models(
207207

208208
if model.kind.is_seed:
209209
# this will produce the original seed file, eg "items.csv"
210+
if model._path is None:
211+
raise ValueError(f"Unhandled model path: {model._path}")
210212
seed_filename = model._path.relative_to(input_paths.seeds)
211213

212214
# seed definition - rename "items.csv" -> "items.sql"
@@ -219,12 +221,18 @@ def _convert_models(
219221
assert isinstance(model.kind, SeedKind)
220222
model.kind.path = str(Path("../seeds", seed_filename))
221223
else:
224+
if model._path is None:
225+
raise ValueError(f"Unhandled model path: {model._path}")
222226
if input_paths.models in model._path.parents:
223227
model_filename = model._path.relative_to(input_paths.models)
224228
elif input_paths.snapshots in model._path.parents:
225229
# /base/path/snapshots/foo.sql -> /output/path/models/dbt_snapshots/foo.sql
226230
model_filename = "dbt_snapshots" / model._path.relative_to(input_paths.snapshots)
231+
elif input_paths.tests in model._path.parents:
232+
# /base/path/tests/foo.sql -> /output/path/audits/foo.sql
233+
model_filename = "dbt_tests" / model._path.relative_to(input_paths.tests)
227234
elif input_paths.packages in model._path.parents:
235+
# /base/path/dbt_packages/foo/models/bar.sql -> /output/path/models/dbt_packages/foo/models/bar.sql
228236
model_filename = c.MIGRATED_DBT_PACKAGES / model._path.relative_to(
229237
input_paths.packages
230238
)
@@ -290,6 +298,8 @@ def _convert_standalone_audits(
290298

291299
audit_definition_string = ";\n".join(stringified)
292300

301+
if audit._path is None:
302+
continue
293303
audit_filename = audit._path.relative_to(input_paths.tests)
294304
audit_output_path = output_paths.audits / audit_filename
295305
audit_output_path.write_text(audit_definition_string)

sqlmesh/lsp/reference.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,9 @@ def get_model_definitions_for_a_path(
164164
else:
165165
return []
166166

167+
if file_path is None:
168+
return []
169+
167170
# Find all possible references
168171
references: t.List[Reference] = []
169172

@@ -246,6 +249,8 @@ def get_model_definitions_for_a_path(
246249
if referenced_model is None:
247250
continue
248251
referenced_model_path = referenced_model._path
252+
if referenced_model_path is None:
253+
continue
249254
# Check whether the path exists
250255
if not referenced_model_path.is_file():
251256
continue
@@ -372,6 +377,9 @@ def get_macro_definitions_for_a_path(
372377
else:
373378
return []
374379

380+
if file_path is None:
381+
return []
382+
375383
references = []
376384
_, config_path = lsp_context.context.config_for_path(
377385
file_path,

sqlmesh/magics.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -287,8 +287,9 @@ def model(self, context: Context, line: str, sql: t.Optional[str] = None) -> Non
287287
if loaded.name == args.model:
288288
model = loaded
289289
else:
290-
with open(model._path, "r", encoding="utf-8") as file:
291-
expressions = parse(file.read(), default_dialect=config.dialect)
290+
if model._path:
291+
with open(model._path, "r", encoding="utf-8") as file:
292+
expressions = parse(file.read(), default_dialect=config.dialect)
292293

293294
formatted = format_model_expressions(
294295
expressions,
@@ -307,8 +308,9 @@ def model(self, context: Context, line: str, sql: t.Optional[str] = None) -> Non
307308
replace=True,
308309
)
309310

310-
with open(model._path, "w", encoding="utf-8") as file:
311-
file.write(formatted)
311+
if model._path:
312+
with open(model._path, "w", encoding="utf-8") as file:
313+
file.write(formatted)
312314

313315
if sql:
314316
context.console.log_success(f"Model `{args.model}` updated")

tests/core/test_model.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3290,7 +3290,7 @@ def runtime_macro(evaluator, **kwargs) -> None:
32903290
model = load_sql_based_model(expressions)
32913291
with pytest.raises(
32923292
ConfigError,
3293-
match=r"Dependencies must be provided explicitly for models that can be rendered only at runtime at.*",
3293+
match=r"Dependencies must be provided explicitly for models that can be rendered only at runtime",
32943294
):
32953295
model.validate_definition()
32963296

@@ -8226,7 +8226,7 @@ def test_physical_version():
82268226

82278227
with pytest.raises(
82288228
ConfigError,
8229-
match=r"Pinning a physical version is only supported for forward only models at.*",
8229+
match=r"Pinning a physical version is only supported for forward only models( at.*)?",
82308230
):
82318231
load_sql_based_model(
82328232
d.parse(

0 commit comments

Comments
 (0)