3030 "nasdaq_companies_summary "
3131 "source:staging.nasdaq_companies_prices_raw"
3232)
33+ REQUIRED_DBT_PACKAGES = ("dbt_project_evaluator" , "dbt_utils" )
3334
3435
3536class CustomizedDagsterDbtTranslator (DagsterDbtTranslator ):
@@ -91,6 +92,21 @@ def _required_env_var(*names: str) -> dg.EnvVar:
9192 raise RuntimeError (f"Set { joined_names } to enable dbt Platform orchestration." )
9293
9394
95+ def _require_dbt_packages (project_dir : Path ) -> None :
96+ """Require explicitly installed dbt packages without network side effects."""
97+ packages_dir = project_dir / "dbt_packages"
98+ missing_packages = [
99+ package
100+ for package in REQUIRED_DBT_PACKAGES
101+ if not (packages_dir / package ).exists ()
102+ ]
103+ if missing_packages :
104+ raise RuntimeError (
105+ "dbt packages are not installed: "
106+ f"{ ', ' .join (missing_packages )} . Run `make dbt-deps`."
107+ )
108+
109+
94110dbt_platform_mode = orchestration_mode in {
95111 "dbt_platform" ,
96112 "dbt_cloud" ,
@@ -156,11 +172,12 @@ def full_dbt_assets(context: dg.AssetExecutionContext, dbt: DbtCloudWorkspace):
156172else :
157173 dbt_project_dir = os .getenv ("DBT_PROJECT_DIR" )
158174 if dbt_project_dir :
159- dbt_project_dir = Path (dbt_project_dir ). resolve ( )
160- if not dbt_project_dir .exists ():
175+ configured_project_dir = Path (dbt_project_dir )
176+ if not configured_project_dir .exists ():
161177 raise FileNotFoundError (
162178 "DBT_PROJECT_DIR environment variable points to a non-existent path."
163179 )
180+ dbt_project_dir = configured_project_dir .resolve ()
164181 else :
165182 current_file = Path (__file__ ).resolve ()
166183 macro_agents_root = current_file .parent .parent .parent
@@ -184,16 +201,14 @@ def full_dbt_assets(context: dg.AssetExecutionContext, dbt: DbtCloudWorkspace):
184201
185202 dbt_project_dir = None
186203 for path in possible_dbt_project_paths :
187- try :
188- abs_path = path .resolve ()
189- if abs_path .exists () and abs_path .is_dir ():
190- if (abs_path / "dbt_project.yml" ).exists () or (
191- abs_path / "dbt_project.yaml"
192- ).exists ():
193- dbt_project_dir = abs_path
194- break
195- except (OSError , RuntimeError ):
204+ if not path .exists () or not path .is_dir ():
196205 continue
206+ abs_path = path .resolve ()
207+ if (abs_path / "dbt_project.yml" ).exists () or (
208+ abs_path / "dbt_project.yaml"
209+ ).exists ():
210+ dbt_project_dir = abs_path
211+ break
197212
198213 if dbt_project_dir is None :
199214 raise FileNotFoundError (
@@ -207,83 +222,28 @@ def full_dbt_assets(context: dg.AssetExecutionContext, dbt: DbtCloudWorkspace):
207222
208223 dbt_project_dir_path = dbt_project_dir
209224
210- dbt_packages_dir = dbt_project_dir_path / "dbt_packages"
211- dbt_utils_dir = (
212- dbt_packages_dir / "dbt_utils" if dbt_packages_dir .exists () else None
213- )
214-
215- if not dbt_packages_dir .exists () or not dbt_utils_dir or not dbt_utils_dir .exists ():
216- import subprocess
217-
218- logger .warning ("dbt packages not found. Running 'dbt deps' (15s timeout)..." )
219- try :
220- result = subprocess .run (
221- ["dbt" , "deps" , "--target" , environment ],
222- cwd = dbt_project_dir_path ,
223- capture_output = True ,
224- text = True ,
225- timeout = 15 ,
226- )
227- if result .returncode != 0 :
228- logger .warning (
229- f"dbt deps failed (non-fatal): { result .stderr or result .stdout } "
230- )
231- else :
232- logger .info ("dbt packages installed successfully" )
233- except subprocess .TimeoutExpired :
234- logger .warning (
235- "dbt deps timed out (network may be unavailable), continuing without packages"
236- )
237- except Exception as e :
238- logger .warning (f"Could not install dbt packages (non-fatal): { e } " )
225+ _require_dbt_packages (dbt_project_dir_path )
239226
240227 dbt_project = DbtProject (
241228 project_dir = dbt_project_dir_path ,
242229 target = environment ,
243230 )
244231
245- dbt_project .prepare_if_dev ()
246-
247232 manifest_path = dbt_project .manifest_path
248- if manifest_path and manifest_path .exists ():
249- logger .info ("Using dbt manifest" )
233+ if not manifest_path .exists ():
234+ raise FileNotFoundError (
235+ f"dbt manifest not found at { manifest_path } . Run `make dbt-manifest`."
236+ )
237+ logger .info ("Using dbt manifest at %s" , manifest_path )
250238
251239 dbt_resource = DbtCliResource (project_dir = dbt_project_dir_path )
252240 dbt_cloud_polling_sensor = None
253241
254242 @dbt_assets (
255- manifest = dbt_project . manifest_path ,
243+ manifest = manifest_path ,
256244 exclude = DBT_NASDAQ_EXCLUDE ,
257245 dagster_dbt_translator = CustomizedDagsterDbtTranslator (),
258246 )
259247 def full_dbt_assets (context : dg .AssetExecutionContext , dbt : DbtCliResource ):
260- dbt_packages_dir = dbt_project_dir_path / "dbt_packages"
261- dbt_utils_dir = (
262- dbt_packages_dir / "dbt_utils" if dbt_packages_dir .exists () else None
263- )
264-
265- if (
266- not dbt_packages_dir .exists ()
267- or not dbt_utils_dir
268- or not dbt_utils_dir .exists ()
269- ):
270- context .log .info (
271- "dbt packages not found. Running 'dbt deps' before build..."
272- )
273- try :
274- deps_result = dbt .cli (["deps" ], context = context ).wait ()
275- return_code = getattr (deps_result , "return_code" , None )
276- if return_code not in (None , 0 ):
277- context .log .error ("Failed to install dbt packages." )
278- raise RuntimeError (
279- "dbt packages installation failed. Please run 'dbt deps' manually"
280- )
281- else :
282- context .log .info ("dbt packages installed successfully" )
283- except Exception as e :
284- context .log .error (f"Could not install dbt packages: { e } " )
285- raise RuntimeError (
286- "dbt packages are required but could not be installed. Please run 'dbt deps' manually"
287- ) from e
288-
248+ _require_dbt_packages (dbt_project_dir_path )
289249 yield from dbt .cli (["build" ], context = context ).stream ()
0 commit comments