4
4
import os
5
5
from pathlib import Path
6
6
from typing import List , Dict , Tuple , Set , Optional
7
+ import yaml
7
8
8
9
from packaging .version import parse as parse_version
9
10
import pydantic
11
+ from dbt_artifacts_parser .parser import parse_run_results , parse_manifest
12
+ from dbt .config .renderer import ProfileRenderer
10
13
11
14
from .utils import getLogger , get_from_dict_with_raise
12
15
from .version import __version__
15
18
logger = getLogger (__name__ )
16
19
17
20
18
- def import_dbt_dependencies ():
19
- try :
20
- from dbt_artifacts_parser .parser import parse_run_results , parse_manifest
21
- from dbt .config .renderer import ProfileRenderer
22
- import yaml
23
- except ImportError :
24
- raise RuntimeError ("Could not import 'dbt' package. You can install it using: pip install 'data-diff[dbt]'." )
25
-
26
- # dbt 1.5+ specific stuff to power selection of models
27
- try :
28
- # ProfileRenderer.render_data() fails without instantiating global flag MACRO_DEBUGGING in dbt-core 1.5
29
- from dbt .flags import set_flags
30
-
31
- set_flags (Namespace (MACRO_DEBUGGING = False ))
32
- except :
33
- pass
34
-
21
+ # getting this dbt_runner will only succeed in dbt-core>=1.5
22
+ # it's needed for `--select` functionality
23
+ def try_get_dbt_runner ():
35
24
try :
36
25
from dbt .cli .main import dbtRunner
37
26
except ImportError :
@@ -42,7 +31,18 @@ def import_dbt_dependencies():
42
31
else :
43
32
dbt_runner = None
44
33
45
- return parse_run_results , parse_manifest , ProfileRenderer , yaml , dbt_runner
34
+ return dbt_runner
35
+
36
+
37
+ # ProfileRenderer.render_data() fails without instantiating global flag MACRO_DEBUGGING in dbt-core 1.5
38
+ # hacky but seems to be a bug on dbt's end
39
+ def try_set_dbt_flags ():
40
+ try :
41
+ from dbt .flags import set_flags
42
+
43
+ set_flags (Namespace (MACRO_DEBUGGING = False ))
44
+ except :
45
+ pass
46
46
47
47
48
48
RUN_RESULTS_PATH = "target/run_results.json"
@@ -77,13 +77,8 @@ class TDatadiffModelConfig(pydantic.BaseModel):
77
77
78
78
class DbtParser :
79
79
def __init__ (self , profiles_dir_override : str , project_dir_override : str ) -> None :
80
- (
81
- self .parse_run_results ,
82
- self .parse_manifest ,
83
- self .ProfileRenderer ,
84
- self .yaml ,
85
- self .dbt_runner ,
86
- ) = import_dbt_dependencies ()
80
+ try_set_dbt_flags ()
81
+ self .dbt_runner = try_get_dbt_runner ()
87
82
self .profiles_dir = Path (profiles_dir_override or default_profiles_dir ())
88
83
self .project_dir = Path (project_dir_override or default_project_dir ())
89
84
self .connection = {}
@@ -173,7 +168,7 @@ def get_run_results_models(self):
173
168
with open (self .project_dir / RUN_RESULTS_PATH ) as run_results :
174
169
logger .info (f"Parsing file { RUN_RESULTS_PATH } " )
175
170
run_results_dict = json .load (run_results )
176
- run_results_obj = self . parse_run_results (run_results = run_results_dict )
171
+ run_results_obj = parse_run_results (run_results = run_results_dict )
177
172
178
173
dbt_version = parse_version (run_results_obj .metadata .dbt_version )
179
174
@@ -199,28 +194,28 @@ def get_manifest_obj(self):
199
194
with open (self .project_dir / MANIFEST_PATH ) as manifest :
200
195
logger .info (f"Parsing file { MANIFEST_PATH } " )
201
196
manifest_dict = json .load (manifest )
202
- manifest_obj = self . parse_manifest (manifest = manifest_dict )
197
+ manifest_obj = parse_manifest (manifest = manifest_dict )
203
198
return manifest_obj
204
199
205
200
def get_project_dict (self ):
206
201
with open (self .project_dir / PROJECT_FILE ) as project :
207
202
logger .info (f"Parsing file { PROJECT_FILE } " )
208
- project_dict = self . yaml .safe_load (project )
203
+ project_dict = yaml .safe_load (project )
209
204
return project_dict
210
205
211
206
def get_connection_creds (self ) -> Tuple [Dict [str , str ], str ]:
212
207
profiles_path = self .profiles_dir / PROFILES_FILE
213
208
with open (profiles_path ) as profiles :
214
209
logger .info (f"Parsing file { profiles_path } " )
215
- profiles = self . yaml .safe_load (profiles )
210
+ profiles = yaml .safe_load (profiles )
216
211
217
212
dbt_profile_var = self .project_dict .get ("profile" )
218
213
219
214
profile = get_from_dict_with_raise (
220
215
profiles , dbt_profile_var , f"No profile '{ dbt_profile_var } ' found in '{ profiles_path } '."
221
216
)
222
217
# values can contain env_vars
223
- rendered_profile = self . ProfileRenderer ().render_data (profile )
218
+ rendered_profile = ProfileRenderer ().render_data (profile )
224
219
profile_target = get_from_dict_with_raise (
225
220
rendered_profile , "target" , f"No target found in profile '{ dbt_profile_var } ' in '{ profiles_path } '."
226
221
)
0 commit comments