Repository: TobikoData/sqlmesh
Pull request #2726 (2024-06-04 00:54:41)

Chore: Update UI models to subclass PydanticModel
This should resolve the Pydantic deprecation warnings in our tests.


Patch:
diff --git a/docs/concepts/models/external_models.md b/docs/concepts/models/external_models.md
index 0c445494..7ff479de 100644
--- a/docs/concepts/models/external_models.md
+++ b/docs/concepts/models/external_models.md
@@ -10,7 +10,7 @@ SQLMesh stores external tables' column information as `EXTERNAL` models.
 
 `EXTERNAL` models consist solely of an external table's column information, so there is no query for SQLMesh to run.
 
-SQLMesh has no information about the data contained in the table represented by an `EXTERNAL` model. The table could be altered or have all its data deleted, and SQLMesh will not detect it. All SQLMesh knows about the table is that it contains the columns specified in the `EXTERNAL` model's `schema.yaml` file (more information below).
+SQLMesh has no information about the data contained in the table represented by an `EXTERNAL` model. The table could be altered or have all its data deleted, and SQLMesh will not detect it. All SQLMesh knows about the table is that it contains the columns specified in the `EXTERNAL` model's file (more information below).
 
 SQLMesh will not take any actions based on an `EXTERNAL` model - its actions are solely determined by the model whose query selects from the `EXTERNAL` model.
 
@@ -18,7 +18,7 @@ The querying model's [`kind`](./model_kinds.md), [`cron`](./overview.md#cron), a
 
 ## Generating an external models schema file
 
-External models can be defined in the `schema.yaml` file in the SQLMesh project's root folder.
+External models can be defined in the `external_models.yaml` file in the SQLMesh project's root folder. The alternative name for this file is `schema.yaml`.
 
 You can create this file by either writing the YAML by hand or allowing SQLMesh to fetch information about external tables with the `create_external_models` CLI command.
 
@@ -38,13 +38,13 @@ FROM
 
 The following sections demonstrate how to create an external model containing `external_db.external_table`'s column information.
 
-All of a SQLMesh project's external models are defined in a single `schema.yaml` file, so the files created below might also include column information for other external models.
+All of a SQLMesh project's external models are defined in a single `external_models.yaml` file, so the files created below might also include column information for other external models.
 
 Alternatively, additional external models can also be defined in the [external_models/](#using-the-external_models-directory) folder.
 
 ### Writing YAML by hand
 
-This example demonstrates the structure of a `schema.yaml` file:
+This example demonstrates the structure of a `external_models.yaml` file:
 
 ```yaml
 - name: external_db.external_table
@@ -65,9 +65,9 @@ The file can be constructed by hand using a standard text editor or IDE.
 
 ### Using CLI
 
-Instead of creating the `schema.yaml` file manually, SQLMesh can generate it for you with the [create_external_models](../../reference/cli.md#create_external_models) CLI command.
+Instead of creating the `external_models.yaml` file manually, SQLMesh can generate it for you with the [create_external_models](../../reference/cli.md#create_external_models) CLI command.
 
-The command identifies all external tables referenced in your SQLMesh project, fetches their column information from the SQL engine's metadata, and then stores the information in the `schema.yaml` file.
+The command identifies all external tables referenced in your SQLMesh project, fetches their column information from the SQL engine's metadata, and then stores the information in the `external_models.yaml` file.
 
 If SQLMesh does not have access to an external table's metadata, the table will be omitted from the file and SQLMesh will issue a warning.
 
@@ -77,18 +77,18 @@ If SQLMesh does not have access to an external table's metadata, the table will
 
 Sometimes, SQLMesh cannot infer the structure of a model and you need to add it manually.
 
-However, since `sqlmesh create_external_models` replaces the `schema.yaml` file, any manual changes you made to that file will be overwritten.
+However, since `sqlmesh create_external_models` replaces the `external_models.yaml` file, any manual changes you made to that file will be overwritten.
 
 The solution is to create the manual model definition files in the `external_models/` directory, like so:
 
 ```
-schema.yaml
-external_models/another_schema.yaml
-external_models/yet_another_schema.yaml
+external_models.yaml
+external_models/more_external_models.yaml
+external_models/even_more_external_models.yaml
 ```
 
-Files in the `external_models` directory must be `.yaml` files that follow the same structure as the `schema.yaml` file.
+Files in the `external_models` directory must be `.yaml` files that follow the same structure as the `external_models.yaml` file.
 
-When SQLMesh loads the definitions, it will first load the models defined in `schema.yaml` followed by any models it can find in `external_models/*.yaml`.
+When SQLMesh loads the definitions, it will first load the models defined in `external_models.yaml` (or `schema.yaml`) and  any models found in `external_models/*.yaml`.
 
-Therefore, you can use `sqlmesh create_external_models` to manage the `schema.yaml` file and then put any models that need to be defined manually inside the `external_models/` directory.
\ No newline at end of file
+Therefore, you can use `sqlmesh create_external_models` to manage the `external_models.yaml` file and then put any models that need to be defined manually inside the `external_models/` directory.
\ No newline at end of file
diff --git a/docs/guides/table_migration.md b/docs/guides/table_migration.md
index ba42bb7f..cb57abd3 100644
--- a/docs/guides/table_migration.md
+++ b/docs/guides/table_migration.md
@@ -39,7 +39,7 @@ Consider an existing table named `my_schema.existing_table`. Migrating this tabl
 
 1. Ensure `my_schema.existing_table` is up to date (has ingested all available source data)
 2. Rename `my_schema.existing_table` to any other name, such as `my_schema.existing_table_historical`
-    - Optionally, enable column-level lineage for the table by making it an [`EXTERNAL` model](../concepts/models/model_kinds.md#external) and adding it to the project's `schema.yaml` file
+    - Optionally, enable column-level lineage for the table by making it an [`EXTERNAL` model](../concepts/models/model_kinds.md#external) and adding it to the project's `external_models.yaml` file
 3. Create a new incremental staging model named `my_schema.existing_table_staging` (see below for code)
 4. Create a new [`VIEW` model](../concepts/models/model_kinds.md#view) named `my_schema.existing_table` (see below for code)
 5. Run `sqlmesh plan` to create and backfill the models
diff --git a/examples/sushi/schema.yaml b/examples/sushi/external_models.yaml
similarity index 100%
rename from examples/sushi/schema.yaml
rename to examples/sushi/external_models.yaml
diff --git a/sqlmesh/core/constants.py b/sqlmesh/core/constants.py
index 772459bc..b2008dd1 100644
--- a/sqlmesh/core/constants.py
+++ b/sqlmesh/core/constants.py
@@ -40,15 +40,16 @@ DEFAULT_LOG_FILE_DIR = "logs"
 """The default directory for log files."""
 
 AUDITS = "audits"
+CACHE = ".cache"
+EXTERNAL_MODELS = "external_models"
 MACROS = "macros"
 METRICS = "metrics"
 MODELS = "models"
-EXTERNAL_MODELS = "external_models"
 SEEDS = "seeds"
 TESTS = "tests"
-CACHE = ".cache"
-SCHEMA_YAML = "schema.yaml"
 
+EXTERNAL_MODELS_YAML = "external_models.yaml"
+EXTERNAL_MODELS_DEPRECATED_YAML = "schema.yaml"
 
 DEFAULT_SCHEMA = "default"
 
diff --git a/sqlmesh/core/context.py b/sqlmesh/core/context.py
index 9d56b6f9..92a3a0d1 100644
--- a/sqlmesh/core/context.py
+++ b/sqlmesh/core/context.py
@@ -81,7 +81,7 @@ from sqlmesh.core.notification_target import (
 from sqlmesh.core.plan import Plan, PlanBuilder
 from sqlmesh.core.reference import ReferenceGraph
 from sqlmesh.core.scheduler import Scheduler
-from sqlmesh.core.schema_loader import create_schema_file
+from sqlmesh.core.schema_loader import create_external_models_file
 from sqlmesh.core.selector import Selector
 from sqlmesh.core.snapshot import (
     DeployabilityIndex,
@@ -1598,17 +1598,22 @@ class GenericContext(BaseContext, t.Generic[C]):
 
     @python_api_analytics
     def create_external_models(self) -> None:
-        """Create a schema file with all external models.
+        """Create a file to document the schema of external models.
 
-        The schema file contains all columns and types of external models, allowing for more robust
-        lineage, validation, and optimizations.
+        The external models file contains all columns and types of external models, allowing for more
+        robust lineage, validation, and optimizations.
         """
         if not self._models:
             self.load(update_schemas=False)
 
         for path, config in self.configs.items():
-            create_schema_file(
-                path=path / c.SCHEMA_YAML,
+            deprecated_yaml = path / c.EXTERNAL_MODELS_DEPRECATED_YAML
+
+            external_models_yaml = (
+                path / c.EXTERNAL_MODELS_YAML if not deprecated_yaml.exists() else deprecated_yaml
+            )
+            create_external_models_file(
+                path=external_models_yaml,
                 models=UniqueKeyDict(
                     "models",
                     {
diff --git a/sqlmesh/core/loader.py b/sqlmesh/core/loader.py
index 856ef668..f9bfeb32 100644
--- a/sqlmesh/core/loader.py
+++ b/sqlmesh/core/loader.py
@@ -182,12 +182,15 @@ class Loader(abc.ABC):
     def _load_external_models(self) -> UniqueKeyDict[str, Model]:
         models: UniqueKeyDict[str, Model] = UniqueKeyDict("models")
         for context_path, config in self._context.configs.items():
-            schema_path = Path(context_path / c.SCHEMA_YAML)
+            external_models_yaml = Path(context_path / c.EXTERNAL_MODELS_YAML)
+            deprecated_yaml = Path(context_path / c.EXTERNAL_MODELS_DEPRECATED_YAML)
             external_models_path = context_path / c.EXTERNAL_MODELS
 
             paths_to_load = []
-            if schema_path.exists():
-                paths_to_load.append(schema_path)
+            if external_models_yaml.exists():
+                paths_to_load.append(external_models_yaml)
+            elif deprecated_yaml.exists():
+                paths_to_load.append(deprecated_yaml)
 
             if external_models_path.exists() and external_models_path.is_dir():
                 paths_to_load.extend(external_models_path.glob("*.yaml"))
diff --git a/sqlmesh/core/schema_loader.py b/sqlmesh/core/schema_loader.py
index e86c1deb..9dc76693 100644
--- a/sqlmesh/core/schema_loader.py
+++ b/sqlmesh/core/schema_loader.py
@@ -16,7 +16,7 @@ from sqlmesh.utils import UniqueKeyDict, yaml
 logger = logging.getLogger(__name__)
 
 
-def create_schema_file(
+def create_external_models_file(
     path: Path,
     models: UniqueKeyDict[str, Model],
     adapter: EngineAdapter,
@@ -24,7 +24,7 @@ def create_schema_file(
     dialect: DialectType,
     max_workers: int = 1,
 ) -> None:
-    """Create or replace a YAML file with model schemas.
+    """Create or replace a YAML file with column and types of all columns in all external models.
 
     Args:
         path: The path to store the YAML file.
diff --git a/web/client/src/library/components/editor/EditorFooter.tsx b/web/client/src/library/components/editor/EditorFooter.tsx
index 96c913a4..7a6f7125 100644
--- a/web/client/src/library/components/editor/EditorFooter.tsx
+++ b/web/client/src/library/components/editor/EditorFooter.tsx
@@ -130,7 +130,8 @@ function getFileType(path?: string): FileType {
   if (path.startsWith('metrics')) return EnumFileType.Metric
   if (['config.yaml', 'config.yml', 'config.py'].includes(path))
     return EnumFileType.Config
-  if (['schema.yaml', 'schema.yml'].includes(path)) return EnumFileType.Schema
+  if (['external_models.yaml', 'schema.yaml'].includes(path))
+    return EnumFileType.Schema
 
   return EnumFileType.Unknown
 }
diff --git a/web/server/models.py b/web/server/models.py
index 2198a599..2f355385 100644
--- a/web/server/models.py
+++ b/web/server/models.py
@@ -5,7 +5,7 @@ import pathlib
 import typing as t
 
 import pydantic
-from pydantic import BaseModel, Field
+from pydantic import Field
 from sqlglot import exp
 from watchfiles import Change
 
@@ -21,6 +21,7 @@ from sqlmesh.core.snapshot.definition import (
 from sqlmesh.utils.date import TimeLike, now_timestamp
 from sqlmesh.utils.pydantic import (
     PYDANTIC_MAJOR_VERSION,
+    PydanticModel,
     field_validator,
     field_validator_v1_args,
 )
@@ -111,7 +112,7 @@ class PlanStage(str, enum.Enum):
     cancel = "cancel"
 
 
-class File(BaseModel):
+class File(PydanticModel):
     name: str
     path: str
     extension: str = ""
@@ -128,25 +129,25 @@ class File(BaseModel):
         return v
 
 
-class Directory(BaseModel):
+class Directory(PydanticModel):
     name: str
     path: str
     directories: t.List[Directory] = []
     files: t.List[File] = []
 
 
-class Meta(BaseModel):
+class Meta(PydanticModel):
     version: str
     has_running_task: bool = False
 
 
-class Reference(BaseModel):
+class Reference(PydanticModel):
     name: str
     expression: str
     unique: bool
 
 
-class ModelDetails(BaseModel):
+class ModelDetails(PydanticModel):
     owner: t.Optional[str] = None
     kind: t.Optional[str] = None
     batch_size: t.Optional[int] = None
@@ -167,13 +168,13 @@ class ModelDetails(BaseModel):
     annotated: t.Optional[bool] = None
 
 
-class Column(BaseModel):
+class Column(PydanticModel):
     name: str
     type: str
     description: t.Optional[str] = None
 
 
-class Model(BaseModel):
+class Model(PydanticModel):
     name: str
     fqn: str
     path: str
@@ -187,7 +188,7 @@ class Model(BaseModel):
     hash: str
 
 
-class ChangeDisplay(BaseModel):
+class ChangeDisplay(PydanticModel):
     name: str
     view_name: str
     node_type: NodeType = NodeType.MODEL
@@ -222,7 +223,7 @@ class ChangeIndirect(ChangeDisplay):
     pass
 
 
-class ModelsDiff(BaseModel):
+class ModelsDiff(PydanticModel):
     direct: t.List[ChangeDirect] = []
     indirect: t.List[ChangeIndirect] = []
     metadata: t.List[ChangeDisplay] = []
@@ -299,13 +300,13 @@ class ModelsDiff(BaseModel):
         )
 
 
-class Environments(BaseModel):
+class Environments(PydanticModel):
     environments: t.Dict[str, Environment] = {}
     pinned_environments: t.Set[str] = set()
     default_target_environment: str = ""
 
 
-class EvaluateInput(BaseModel):
+class EvaluateInput(PydanticModel):
     model: str
     start: TimeLike
     end: TimeLike
@@ -313,12 +314,12 @@ class EvaluateInput(BaseModel):
     limit: int = 1000
 
 
-class FetchdfInput(BaseModel):
+class FetchdfInput(PydanticModel):
     sql: str
     limit: int = 1000
 
 
-class RenderInput(BaseModel):
+class RenderInput(PydanticModel):
     model: str
     start: t.Optional[TimeLike] = None
     end: t.Optional[TimeLike] = None
@@ -328,12 +329,12 @@ class RenderInput(BaseModel):
     dialect: t.Optional[str] = None
 
 
-class PlanDates(BaseModel):
+class PlanDates(PydanticModel):
     start: t.Optional[TimeLike] = None
     end: t.Optional[TimeLike] = None
 
 
-class PlanOptions(BaseModel):
+class PlanOptions(PydanticModel):
     skip_tests: bool = False
     skip_backfill: bool = False
     no_gaps: bool = False
@@ -352,17 +353,17 @@ class PlanOptions(BaseModel):
         return v
 
 
-class LineageColumn(BaseModel):
+class LineageColumn(PydanticModel):
     source: t.Optional[str] = None
     expression: t.Optional[str] = None
     models: t.Dict[str, t.Set[str]]
 
 
-class Query(BaseModel):
+class Query(PydanticModel):
     sql: str
 
 
-class ApiExceptionPayload(BaseModel):
+class ApiExceptionPayload(PydanticModel):
     timestamp: int
     message: str
     origin: str
@@ -374,7 +375,7 @@ class ApiExceptionPayload(BaseModel):
     stack: t.Optional[t.List[str]] = None
 
 
-class SchemaDiff(BaseModel):
+class SchemaDiff(PydanticModel):
     source: str
     target: str
     source_schema: t.Dict[str, str]
@@ -398,7 +399,7 @@ class SchemaDiff(BaseModel):
         return v
 
 
-class RowDiff(BaseModel):
+class RowDiff(PydanticModel):
     source: str
     target: str
     stats: t.Dict[str, float]
@@ -408,13 +409,13 @@ class RowDiff(BaseModel):
     count_pct_change: float
 
 
-class TableDiff(BaseModel):
+class TableDiff(PydanticModel):
     schema_diff: SchemaDiff
     row_diff: RowDiff
     on: t.List[t.List[str]]
 
 
-class TestCase(BaseModel):
+class TestCase(PydanticModel):
     name: str
     path: pathlib.Path
 
@@ -427,7 +428,7 @@ class TestSkipped(TestCase):
     reason: str
 
 
-class TestResult(BaseModel):
+class TestResult(PydanticModel):
     tests_run: int
     failures: t.List[TestErrorOrFailure]
     errors: t.List[TestErrorOrFailure]
@@ -435,14 +436,14 @@ class TestResult(BaseModel):
     successes: t.List[TestCase]
 
 
-class ArtifactChange(BaseModel):
+class ArtifactChange(PydanticModel):
     change: Change
     path: str
     type: t.Optional[ArtifactType] = None
     file: t.Optional[File] = None
 
 
-class ReportTestsResult(BaseModel):
+class ReportTestsResult(PydanticModel):
     message: str
 
 
@@ -473,7 +474,7 @@ class BackfillTask(ChangeDisplay):
     interval: t.Optional[t.List[str]] = None
 
 
-class TrackableMeta(BaseModel):
+class TrackableMeta(PydanticModel):
     status: Status = Status.INIT
     start: int = Field(default_factory=now_timestamp)
     end: t.Optional[int] = None
@@ -489,7 +490,7 @@ class TrackableMeta(BaseModel):
         return data
 
 
-class Trackable(BaseModel):
+class Trackable(PydanticModel):
     meta: TrackableMeta = Field(default_factory=TrackableMeta)
 
     def stop(self, success: bool = True) -> None:
@@ -514,7 +515,7 @@ class PlanStageCancel(Trackable):
     pass
 
 
-class PlanChanges(BaseModel):
+class PlanChanges(PydanticModel):
     # can't have a set of pydantic models: https://github.com/pydantic/pydantic/issues/1090
     added: t.Optional[t.List[ChangeDisplay]] = None
     removed: t.Optional[t.List[ChangeDisplay]] = None
@@ -574,6 +575,6 @@ class PlanCancelStageTracker(PlanStageTracker):
     cancel: t.Optional[PlanStageCancel] = None
 
 
-class FormatFileStatus(BaseModel):
+class FormatFileStatus(PydanticModel):
     path: str
     status: Status = Status.INIT


Test patch:
diff --git a/docs/concepts/tests.md b/docs/concepts/tests.md
index 3f4d176b..d0250780 100644
--- a/docs/concepts/tests.md
+++ b/docs/concepts/tests.md
@@ -474,7 +474,7 @@ It's not always possible to correctly interpret certain values in a unit test wi
 
 To avoid this ambiguity, SQLMesh needs to know the columns' types. By default, it will try to infer these types based on the model definitions, but they can also be explicitly specified:
 
-- in the [`schema.yaml`](models/external_models.md#generating-an-external-models-schema-file) file (for external models)
+- in the [`external_models.yaml`](models/external_models.md#generating-an-external-models-schema-file) file (for external models)
 - using the [`columns`](models/overview.md#columns) model property
 - using the [`columns`](#creating_tests) attribute of the unit test
 
diff --git a/sqlmesh/core/test/definition.py b/sqlmesh/core/test/definition.py
index 82119f2d..bd6bba63 100644
--- a/sqlmesh/core/test/definition.py
+++ b/sqlmesh/core/test/definition.py
@@ -142,7 +142,7 @@ class ModelTest(unittest.TestCase):
                             _raise_error(
                                 f"Failed to infer the data type of column '{col}' for '{name}'. This issue can be "
                                 "mitigated by casting the column in the model definition, setting its type in "
-                                "schema.yaml if it's an external model, setting the model's 'columns' property, "
+                                "external_models.yaml if it's an external model, setting the model's 'columns' property, "
                                 "or setting its 'columns' mapping in the test itself",
                                 self.path,
                             )
diff --git a/tests/core/test_context.py b/tests/core/test_context.py
index 6d266bbb..c12862fe 100644
--- a/tests/core/test_context.py
+++ b/tests/core/test_context.py
@@ -668,7 +668,7 @@ def test_load_external_models(copy_to_temp_path):
 
     assert len(external_model_names) > 0
 
-    # from schema.yaml in root dir
+    # from default external_models.yaml in root dir
     assert "raw.demographics" in external_model_names
 
     # from external_models/model1.yaml
diff --git a/tests/core/test_schema_loader.py b/tests/core/test_schema_loader.py
index 1e758e60..8b36f5b5 100644
--- a/tests/core/test_schema_loader.py
+++ b/tests/core/test_schema_loader.py
@@ -11,7 +11,7 @@ from sqlmesh.core.config import Config, DuckDBConnectionConfig, GatewayConfig
 from sqlmesh.core.context import Context
 from sqlmesh.core.dialect import parse
 from sqlmesh.core.model import SqlModel, create_external_model, load_sql_based_model
-from sqlmesh.core.schema_loader import create_schema_file
+from sqlmesh.core.schema_loader import create_external_models_file
 from sqlmesh.core.snapshot import SnapshotChangeCategory
 from sqlmesh.utils.yaml import YAML
 
@@ -114,9 +114,9 @@ def test_no_internal_model_conversion(tmp_path: Path, make_snapshot, mocker: Moc
     model_a = SqlModel(name="a", query=parse_one("select * FROM model_b, tbl_c"))
     model_b = SqlModel(name="b", query=parse_one("select * FROM `tbl-d`", read="bigquery"))
 
-    schema_file = tmp_path / c.SCHEMA_YAML
-    create_schema_file(
-        schema_file,
+    filename = tmp_path / c.EXTERNAL_MODELS_YAML
+    create_external_models_file(
+        filename,
         {  # type: ignore
             "a": model_a,
             "b": model_b,
@@ -126,7 +126,7 @@ def test_no_internal_model_conversion(tmp_path: Path, make_snapshot, mocker: Moc
         "bigquery",
     )
 
-    with open(schema_file, "r", encoding="utf8") as fd:
+    with open(filename, "r", encoding="utf8") as fd:
         schema = YAML().load(fd)
 
     assert len(schema) == 2
@@ -144,11 +144,11 @@ def test_missing_table(tmp_path: Path):
     context = Context(paths=[str(tmp_path.absolute())], config=config)
     model = SqlModel(name="a", query=parse_one("select * FROM tbl_source"))
 
-    schema_file = tmp_path / c.SCHEMA_YAML
+    filename = tmp_path / c.EXTERNAL_MODELS_YAML
     logger = logging.getLogger("sqlmesh.core.schema_loader")
     with patch.object(logger, "warning") as mock_logger:
-        create_schema_file(
-            schema_file,
+        create_external_models_file(
+            filename,
             {"a": model},  # type: ignore
             context.engine_adapter,
             context.state_reader,
@@ -156,6 +156,6 @@ def test_missing_table(tmp_path: Path):
         )
     assert """Unable to get schema for '"tbl_source"'""" in mock_logger.call_args[0][0]
 
-    with open(schema_file, "r", encoding="utf8") as fd:
+    with open(filename, "r", encoding="utf8") as fd:
         schema = YAML().load(fd)
     assert len(schema) == 0
diff --git a/tests/core/test_test.py b/tests/core/test_test.py
index df5ca464..cc20db2d 100644
--- a/tests/core/test_test.py
+++ b/tests/core/test_test.py
@@ -843,7 +843,7 @@ test_foo:
         expected_msg=(
             """Failed to infer the data type of column 'value' for '"raw"'. This issue can """
             "be mitigated by casting the column in the model definition, setting its type in "
-            "schema.yaml if it's an external model, setting the model's 'columns' property, "
+            "external_models.yaml if it's an external model, setting the model's 'columns' property, "
             "or setting its 'columns' mapping in the test itself\n"
         ),
     )
diff --git a/tests/integrations/jupyter/test_magics.py b/tests/integrations/jupyter/test_magics.py
index a84a2b28..66c8eb7c 100644
--- a/tests/integrations/jupyter/test_magics.py
+++ b/tests/integrations/jupyter/test_magics.py
@@ -600,7 +600,7 @@ def test_migrate(
 
 @pytest.mark.slow
 def test_create_external_models(notebook, loaded_sushi_context):
-    external_model_file = loaded_sushi_context.path / "schema.yaml"
+    external_model_file = loaded_sushi_context.path / "external_models.yaml"
     external_model_file.unlink()
     assert not external_model_file.exists()
     loaded_sushi_context.load()