6262 Config ,
6363 load_configs ,
6464)
65+ from sqlmesh .core .config .connection import ConnectionConfig
6566from sqlmesh .core .config .loader import C
67+ from sqlmesh .core .config .root import RegexKeyDict
6668from sqlmesh .core .console import get_console
6769from sqlmesh .core .context_diff import ContextDiff
6870from sqlmesh .core .dialect import (
9193from sqlmesh .core .plan .definition import UserProvidedFlags
9294from sqlmesh .core .reference import ReferenceGraph
9395from sqlmesh .core .scheduler import Scheduler , CompletionStatus
96+ from sqlmesh .core .schema_diff import SchemaDiffer
9497from sqlmesh .core .schema_loader import create_external_models_file
9598from sqlmesh .core .selector import Selector
9699from sqlmesh .core .snapshot import (
@@ -367,6 +370,9 @@ def __init__(
367370 self ._excluded_requirements : t .Set [str ] = set ()
368371 self ._default_catalog : t .Optional [str ] = None
369372 self ._default_catalog_per_gateway : t .Optional [t .Dict [str , str ]] = None
373+ self ._engine_adapter : t .Optional [EngineAdapter ] = None
374+ self ._connection_config : t .Optional [ConnectionConfig ] = None
375+ self ._test_connection_config : t .Optional [ConnectionConfig ] = None
370376 self ._linters : t .Dict [str , Linter ] = {}
371377 self ._loaded : bool = False
372378
@@ -407,24 +413,15 @@ def __init__(
407413 for path , config in self .configs .items ()
408414 ]
409415
410- self ._connection_config = self . config . get_connection ( self . gateway )
416+ self ._concurrent_tasks = concurrent_tasks
411417 self ._state_connection_config = (
412- self .config .get_state_connection (self .gateway ) or self ._connection_config
418+ self .config .get_state_connection (self .gateway ) or self .connection_config
413419 )
414- self .concurrent_tasks = concurrent_tasks or self ._connection_config .concurrent_tasks
415-
416- self ._engine_adapters : t .Dict [str , EngineAdapter ] = {
417- self .selected_gateway : self ._connection_config .create_engine_adapter ()
418- }
419420
420421 self ._snapshot_evaluator : t .Optional [SnapshotEvaluator ] = None
421422
422423 self .console = get_console ()
423- setattr (self .console , "dialect" , self .engine_adapter .dialect )
424-
425- self ._test_connection_config = self .config .get_test_connection (
426- self .gateway , self .default_catalog , default_catalog_dialect = self .engine_adapter .DIALECT
427- )
424+ setattr (self .console , "dialect" , self .config .dialect )
428425
429426 self ._provided_state_sync : t .Optional [StateSync ] = state_sync
430427 self ._state_sync : t .Optional [StateSync ] = None
@@ -435,14 +432,6 @@ def __init__(
435432 self .users = list ({user .username : user for user in self .users }.values ())
436433 self ._register_notification_targets ()
437434
438- if (
439- self .config .environment_catalog_mapping
440- and not self .engine_adapter .catalog_support .is_multi_catalog_supported
441- ):
442- raise SQLMeshError (
443- "Environment catalog mapping is only supported for engine adapters that support multiple catalogs"
444- )
445-
446435 if load :
447436 self .load ()
448437
@@ -453,7 +442,9 @@ def default_dialect(self) -> t.Optional[str]:
453442 @property
454443 def engine_adapter (self ) -> EngineAdapter :
455444 """Returns the default engine adapter."""
456- return self ._engine_adapters [self .selected_gateway ]
445+ if self ._engine_adapter is None :
446+ self ._engine_adapter = self .connection_config .create_engine_adapter ()
447+ return self ._engine_adapter
457448
458449 @property
459450 def snapshot_evaluator (self ) -> SnapshotEvaluator :
@@ -980,8 +971,8 @@ def requirements(self) -> t.Dict[str, str]:
980971
981972 @property
982973 def default_catalog (self ) -> t .Optional [str ]:
983- if self ._default_catalog is None :
984- self ._default_catalog = self ._scheduler . get_default_catalog ( self )
974+ if self ._default_catalog is None and self . default_catalog_per_gateway :
975+ self ._default_catalog = self .default_catalog_per_gateway [ self . selected_gateway ]
985976 return self ._default_catalog
986977
987978 @python_api_analytics
@@ -1538,7 +1529,7 @@ def plan_builder(
15381529 allow_destructive_models = expanded_destructive_models ,
15391530 environment_ttl = environment_ttl ,
15401531 environment_suffix_target = self .config .environment_suffix_target ,
1541- environment_catalog_mapping = self .config . environment_catalog_mapping ,
1532+ environment_catalog_mapping = self .environment_catalog_mapping ,
15421533 categorizer_config = categorizer_config or self .auto_categorize_changes ,
15431534 auto_categorization_enabled = not no_auto_categorization ,
15441535 effective_from = effective_from ,
@@ -1550,7 +1541,7 @@ def plan_builder(
15501541 ),
15511542 end_bounded = not run ,
15521543 ensure_finalized_snapshots = self .config .plan .use_finalized_state ,
1553- engine_schema_differ = self . engine_adapter . SCHEMA_DIFFER ,
1544+ engine_schema_differ = SchemaDiffer (), # TODO: fix to properly handle it
15541545 interval_end_per_model = max_interval_end_per_model ,
15551546 console = self .console ,
15561547 user_provided_flags = user_provided_flags ,
@@ -1639,7 +1630,7 @@ def diff(self, environment: t.Optional[str] = None, detailed: bool = False) -> b
16391630 self .console .show_model_difference_summary (
16401631 context_diff ,
16411632 EnvironmentNamingInfo .from_environment_catalog_mapping (
1642- self .config . environment_catalog_mapping ,
1633+ self .environment_catalog_mapping ,
16431634 name = environment ,
16441635 suffix_target = self .config .environment_suffix_target ,
16451636 normalize_name = context_diff .normalize_environment_name ,
@@ -1993,7 +1984,7 @@ def create_test(
19931984
19941985 try :
19951986 model_to_test = self .get_model (model , raise_if_missing = True )
1996- test_adapter = self ._test_connection_config .create_engine_adapter (
1987+ test_adapter = self .test_connection_config .create_engine_adapter (
19971988 register_comments_override = False
19981989 )
19991990
@@ -2039,7 +2030,7 @@ def test(
20392030 preserve_fixtures = preserve_fixtures ,
20402031 stream = stream ,
20412032 default_catalog = self .default_catalog ,
2042- default_catalog_dialect = self .engine_adapter . DIALECT ,
2033+ default_catalog_dialect = self .config . dialect or "" ,
20432034 )
20442035
20452036 @python_api_analytics
@@ -2478,7 +2469,7 @@ def _run_plan_tests(
24782469 self .console .log_test_results (
24792470 result ,
24802471 test_output ,
2481- self ._test_connection_config ._engine_adapter .DIALECT ,
2472+ self .test_connection_config ._engine_adapter .DIALECT ,
24822473 )
24832474 if not result .wasSuccessful ():
24842475 raise PlanError (
@@ -2499,7 +2490,7 @@ def _model_tables(self) -> t.Dict[str, str]:
24992490 if snapshot .version
25002491 else snapshot .qualified_view_name .for_environment (
25012492 EnvironmentNamingInfo .from_environment_catalog_mapping (
2502- self .config . environment_catalog_mapping ,
2493+ self .environment_catalog_mapping ,
25032494 name = c .PROD ,
25042495 suffix_target = self .config .environment_suffix_target ,
25052496 )
@@ -2511,24 +2502,63 @@ def _model_tables(self) -> t.Dict[str, str]:
25112502 @cached_property
25122503 def engine_adapters (self ) -> t .Dict [str , EngineAdapter ]:
25132504 """Returns all the engine adapters for the gateways defined in the configuration."""
2505+ adapters : t .Dict [str , EngineAdapter ] = {self .selected_gateway : self .engine_adapter }
25142506 for gateway_name in self .config .gateways :
25152507 if gateway_name != self .selected_gateway :
25162508 connection = self .config .get_connection (gateway_name )
25172509 adapter = connection .create_engine_adapter (concurrent_tasks = self .concurrent_tasks )
2518- self . _engine_adapters [gateway_name ] = adapter
2519- return self . _engine_adapters
2510+ adapters [gateway_name ] = adapter
2511+ return adapters
25202512
25212513 @cached_property
25222514 def default_catalog_per_gateway (self ) -> t .Dict [str , str ]:
25232515 """Returns the default catalogs for each engine adapter."""
25242516 if self ._default_catalog_per_gateway is None :
2525- self ._default_catalog_per_gateway = {
2526- name : adapter .default_catalog
2527- for name , adapter in self .engine_adapters .items ()
2528- if adapter .default_catalog
2529- }
2517+ self ._default_catalog_per_gateway = self ._scheduler .get_default_catalog_per_gateway (
2518+ self
2519+ )
25302520 return self ._default_catalog_per_gateway
25312521
2522+ @cached_property
2523+ def concurrent_tasks (self ) -> int :
2524+ if self ._concurrent_tasks is None :
2525+ self ._concurrent_tasks = self .connection_config .concurrent_tasks
2526+ return self ._concurrent_tasks
2527+
2528+ @cached_property
2529+ def connection_config (self ) -> ConnectionConfig :
2530+ if self ._connection_config is None :
2531+ self ._connection_config = self .config .get_connection (self .selected_gateway )
2532+ return self ._connection_config
2533+
2534+ @cached_property
2535+ def test_connection_config (self ) -> ConnectionConfig :
2536+ if self ._test_connection_config is None :
2537+ self ._test_connection_config = self .config .get_test_connection (
2538+ self .gateway ,
2539+ self .default_catalog ,
2540+ default_catalog_dialect = self .engine_adapter .DIALECT ,
2541+ )
2542+ return self ._test_connection_config
2543+
2544+ @cached_property
2545+ def environment_catalog_mapping (self ) -> RegexKeyDict :
2546+ engine_adapter = None
2547+ try :
2548+ engine_adapter = self .engine_adapter
2549+ except Exception :
2550+ pass
2551+
2552+ if (
2553+ self .config .environment_catalog_mapping
2554+ and engine_adapter
2555+ and not self .engine_adapter .catalog_support .is_multi_catalog_supported
2556+ ):
2557+ raise SQLMeshError (
2558+ "Environment catalog mapping is only supported for engine adapters that support multiple catalogs"
2559+ )
2560+ return self .config .environment_catalog_mapping
2561+
25322562 def _get_engine_adapter (self , gateway : t .Optional [str ] = None ) -> EngineAdapter :
25332563 if gateway :
25342564 if adapter := self .engine_adapters .get (gateway ):
0 commit comments