44import typing as t
55from pathlib import Path
66from itertools import zip_longest
7+ import abc
78
89from sqlglot import exp
910from sqlglot .errors import ParseError
2728 from sqlmesh .core .state_sync import StateReader
2829
2930
30- class Selector :
31+ class Selector ( abc . ABC ) :
3132 def __init__ (
3233 self ,
3334 state_reader : StateReader ,
@@ -37,7 +38,6 @@ def __init__(
3738 default_catalog : t .Optional [str ] = None ,
3839 dialect : t .Optional [str ] = None ,
3940 cache_dir : t .Optional [Path ] = None ,
40- dbt_mode : bool = False ,
4141 ):
4242 self ._state_reader = state_reader
4343 self ._models = models
@@ -46,7 +46,6 @@ def __init__(
4646 self ._default_catalog = default_catalog
4747 self ._dialect = dialect
4848 self ._git_client = GitClient (context_path )
49- self ._dbt_mode = dbt_mode
5049
5150 if dag is None :
5251 self ._dag : DAG [str ] = DAG ()
@@ -243,26 +242,37 @@ def evaluate(node: exp.Expression) -> t.Set[str]:
243242
244243 return evaluate (node )
245244
246- def _model_fqn (self , model : Model ) -> str :
247- if self ._dbt_mode :
248- dbt_fqn = model .dbt_fqn
249- if dbt_fqn is None :
250- raise SQLMeshError ("Expecting dbt node information to be populated; it wasnt" )
251- return dbt_fqn
252- return model .fqn
245+ @abc .abstractmethod
246+ def _model_name (self , model : Model ) -> str :
247+ """Given a model, return the name that a selector pattern contining wildcards should be fnmatch'd on"""
248+ pass
249+
250+ @abc .abstractmethod
251+ def _pattern_to_model_fqns (self , pattern : str , all_models : t .Dict [str , Model ]) -> t .Set [str ]:
252+ """Given a pattern, return the keys of the matching models from :all_models"""
253+ pass
254+
255+
256+ class NativeSelector (Selector ):
257+ """Implementation of selectors that matches objects based on SQLMesh native names"""
253258
254259 def _model_name (self , model : Model ) -> str :
255- if self ._dbt_mode :
256- # dbt always matches on the fqn, not the name
257- return self ._model_fqn (model )
258260 return model .name
259261
260262 def _pattern_to_model_fqns (self , pattern : str , all_models : t .Dict [str , Model ]) -> t .Set [str ]:
261- # note: all_models should be keyed by sqlmesh fqn, not dbt fqn
262- if not self ._dbt_mode :
263- fqn = normalize_model_name (pattern , self ._default_catalog , self ._dialect )
264- return {fqn } if fqn in all_models else set ()
263+ fqn = normalize_model_name (pattern , self ._default_catalog , self ._dialect )
264+ return {fqn } if fqn in all_models else set ()
265265
266+
267+ class DbtSelector (Selector ):
268+ """Implementation of selectors that matches objects based on the DBT names instead of the SQLMesh native names"""
269+
270+ def _model_name (self , model : Model ) -> str :
271+ if dbt_fqn := model .dbt_fqn :
272+ return dbt_fqn
273+ raise SQLMeshError ("dbt node information must be populated to use dbt selectors" )
274+
275+ def _pattern_to_model_fqns (self , pattern : str , all_models : t .Dict [str , Model ]) -> t .Set [str ]:
266276 # a pattern like "staging.customers" should match a model called "jaffle_shop.staging.customers"
267277 # but not a model called "jaffle_shop.customers.staging"
268278 # also a pattern like "aging" should not match "staging" so we need to consider components; not substrings
0 commit comments