@@ -68,6 +68,13 @@ class LoadedProject:
6868
6969
7070class CacheBase (abc .ABC ):
71+ @abc .abstractmethod
72+ def get_or_load_models (
73+ self , target_path : Path , loader : t .Callable [[], t .List [Model ]]
74+ ) -> t .List [Model ]:
75+ """Get or load all models from cache."""
76+ pass
77+
7178 @abc .abstractmethod
7279 def put (self , models : t .List [Model ], path : Path ) -> bool :
7380 pass
@@ -291,31 +298,30 @@ def _load_external_models(
291298 if external_models_path .exists () and external_models_path .is_dir ():
292299 paths_to_load .extend (self ._glob_paths (external_models_path , extension = ".yaml" ))
293300
301+ def _load (path : Path ) -> t .List [Model ]:
302+ try :
303+ with open (path , "r" , encoding = "utf-8" ) as file :
304+ return [
305+ create_external_model (
306+ defaults = self .config .model_defaults .dict (),
307+ path = path ,
308+ project = self .config .project ,
309+ audit_definitions = audits ,
310+ ** {
311+ "dialect" : self .config .model_defaults .dialect ,
312+ "default_catalog" : self .context .default_catalog ,
313+ ** row ,
314+ },
315+ )
316+ for row in YAML ().load (file .read ())
317+ ]
318+ except Exception as ex :
319+ raise ConfigError (self ._failed_to_load_model_error (path , ex ))
320+
294321 for path in paths_to_load :
295322 self ._track_file (path )
296- external_models = cache .get (path )
297323
298- if not external_models :
299- try :
300- with open (path , "r" , encoding = "utf-8" ) as file :
301- external_models = [
302- create_external_model (
303- defaults = self .config .model_defaults .dict (),
304- path = path ,
305- project = self .config .project ,
306- audit_definitions = audits ,
307- ** {
308- "dialect" : self .config .model_defaults .dialect ,
309- "default_catalog" : self .context .default_catalog ,
310- ** row ,
311- },
312- )
313- for row in YAML ().load (file .read ())
314- ]
315-
316- cache .put (external_models , path )
317- except Exception as ex :
318- raise ConfigError (f"Failed to load model definition at '{ path } '.\n { ex } " )
324+ external_models = cache .get_or_load_models (path , lambda : _load (path ))
319325
320326 # external models with no explicit gateway defined form the base set
321327 for model in external_models :
@@ -843,6 +849,20 @@ def __init__(self, loader: SqlMeshLoader, config_path: Path):
843849 self .config_path = config_path
844850 self ._model_cache = ModelCache (self .config_path / c .CACHE )
845851
852+ def get_or_load_models (
853+ self , target_path : Path , loader : t .Callable [[], t .List [Model ]]
854+ ) -> t .List [Model ]:
855+ models = self ._model_cache .get_or_load (
856+ self ._cache_entry_name (target_path ),
857+ self ._model_cache_entry_id (target_path ),
858+ loader = loader ,
859+ )
860+
861+ for model in models :
862+ model ._path = target_path
863+
864+ return models
865+
846866 def put (self , models : t .List [Model ], path : Path ) -> bool :
847867 return self ._model_cache .put (
848868 models ,
0 commit comments