diff --git a/sqlmesh/core/model/definition.py b/sqlmesh/core/model/definition.py index e8e122dece..7c56e01c0b 100644 --- a/sqlmesh/core/model/definition.py +++ b/sqlmesh/core/model/definition.py @@ -2361,7 +2361,15 @@ def load_sql_based_model( **meta_fields, ) - kind = common_kwargs.pop("kind", ModelMeta.all_field_infos()["kind"].default) + kind = common_kwargs.pop("kind", None) + if kind is None: + # Use the project's default kind, if any, before falling back to the ModelMeta default + default_kind = rendered_defaults.get("kind") + kind = ( + create_model_kind(default_kind, dialect, rendered_defaults) + if default_kind is not None + else ModelMeta.all_field_infos()["kind"].default + ) if kind.name != ModelKindName.SEED: return create_sql_model( diff --git a/tests/core/test_model.py b/tests/core/test_model.py index c9045c9506..1e8033d657 100644 --- a/tests/core/test_model.py +++ b/tests/core/test_model.py @@ -7004,6 +7004,33 @@ def test_end_no_start(): load_sql_based_model(expressions, defaults={"start": "2023-01-01"}) +def test_model_defaults_kind(): + defaults = ModelDefaultsConfig(dialect="duckdb", kind="full").dict() + + model = load_sql_based_model( + parse( + """ + MODEL (name db.table); + SELECT 1 AS a + """ + ), + defaults=defaults, + ) + assert model.kind.name == ModelKindName.FULL + + # a kind set on the model itself still takes precedence + model = load_sql_based_model( + parse( + """ + MODEL (name db.table, kind VIEW); + SELECT 1 AS a + """ + ), + defaults=defaults, + ) + assert model.kind.name == ModelKindName.VIEW + + def test_variables(): @macro() def test_macro_var(evaluator) -> exp.Expr: