|
2 | 2 | import os |
3 | 3 | import re |
4 | 4 | from dataclasses import dataclass |
5 | | -from typing import Any, Dict, List, Optional, Union |
| 5 | +from typing import Any, Dict, List, Optional |
6 | 6 |
|
7 | 7 | import yaml |
8 | 8 |
|
9 | 9 | from elementary.clients.dbt.base_dbt_runner import BaseDbtRunner |
| 10 | +from elementary.clients.dbt.databricks_patch import apply_databricks_patch |
10 | 11 | from elementary.clients.dbt.dbt_log import parse_dbt_output |
11 | 12 | from elementary.exceptions.exceptions import DbtCommandError, DbtLsCommandError |
12 | 13 | from elementary.monitor.dbt_project_utils import is_dbt_package_up_to_date |
@@ -56,8 +57,7 @@ def __init__( |
56 | 57 |
|
57 | 58 | # Apply databricks compatibility patch for version 1.10.2 only once |
58 | 59 | if not CommandLineDbtRunner._dbx_patch_applied: |
59 | | - self._apply_databricks_compatibility_patch() |
60 | | - CommandLineDbtRunner._dbx_patch_applied = True |
| 60 | + CommandLineDbtRunner._dbx_patch_applied = apply_databricks_patch() |
61 | 61 |
|
62 | 62 | if force_dbt_deps: |
63 | 63 | self.deps() |
@@ -326,114 +326,3 @@ def _run_deps_if_needed(self): |
326 | 326 |
|
327 | 327 | if should_run_deps: |
328 | 328 | self.deps() |
329 | | - |
330 | | - def _apply_databricks_compatibility_patch(self): |
331 | | - """Apply monkey patch to fix dbt-databricks 1.10.2 compatibility issues""" |
332 | | - try: |
333 | | - from typing import Any, Optional |
334 | | - |
335 | | - from dbt.adapters.databricks import parse_model # type: ignore |
336 | | - |
337 | | - def is_unsupported_object(model: Any) -> bool: |
338 | | - """Check if the object is a Macro or other unsupported type""" |
339 | | - return hasattr(model, "__class__") and "Macro" in str(model.__class__) |
340 | | - |
341 | | - def safe_catalog_name(model: Any) -> str: |
342 | | - try: |
343 | | - if is_unsupported_object(model): |
344 | | - logger.debug( |
345 | | - "Received unsupported object type for catalog_name, using unity as default" |
346 | | - ) |
347 | | - return "unity" |
348 | | - # Handle RelationConfig objects |
349 | | - if ( |
350 | | - hasattr(model, "config") |
351 | | - and model.config |
352 | | - and hasattr(model.config, "get") |
353 | | - ): |
354 | | - catalog = model.config.get("catalog") |
355 | | - if catalog: |
356 | | - return catalog |
357 | | - # Fallback to unity catalog |
358 | | - return "unity" |
359 | | - except Exception as e: |
360 | | - logger.debug( |
361 | | - f"Failed to parse catalog name from model: {e}. Using unity as default." |
362 | | - ) |
363 | | - return "unity" |
364 | | - |
365 | | - def safe_file_format(model: Any) -> Optional[str]: |
366 | | - try: |
367 | | - if is_unsupported_object(model): |
368 | | - return None |
369 | | - return safe_get(model, "file_format") |
370 | | - except Exception as e: |
371 | | - logger.debug(f"Failed to get file_format from model: {e}") |
372 | | - return None |
373 | | - |
374 | | - def safe_location_path(model: Any) -> Optional[str]: |
375 | | - try: |
376 | | - if is_unsupported_object(model): |
377 | | - return None |
378 | | - if not hasattr(model, "config") or not model.config: |
379 | | - return None |
380 | | - if model.config.get("include_full_name_in_path"): |
381 | | - return f"{model.database}/{model.schema}/{model.identifier}" |
382 | | - return model.identifier if hasattr(model, "identifier") else None |
383 | | - except Exception as e: |
384 | | - logger.debug(f"Failed to get location_path from model: {e}") |
385 | | - return None |
386 | | - |
387 | | - def safe_location_root(model: Any) -> Optional[str]: |
388 | | - try: |
389 | | - if is_unsupported_object(model): |
390 | | - return None |
391 | | - return safe_get(model, "location_root") |
392 | | - except Exception as e: |
393 | | - logger.debug(f"Failed to get location_root from model: {e}") |
394 | | - return None |
395 | | - |
396 | | - def safe_table_format(model: Any) -> Optional[str]: |
397 | | - try: |
398 | | - if is_unsupported_object(model): |
399 | | - return None |
400 | | - return safe_get(model, "table_format") |
401 | | - except Exception as e: |
402 | | - logger.debug(f"Failed to get table_format from model: {e}") |
403 | | - return None |
404 | | - |
405 | | - def safe_get( |
406 | | - model: Any, setting: str, case_sensitive: Union[bool, None] = False |
407 | | - ) -> Union[str, None]: |
408 | | - try: |
409 | | - if is_unsupported_object(model): |
410 | | - return None |
411 | | - # Check if model has config attribute |
412 | | - if not hasattr(model, "config") or not model.config: |
413 | | - return None |
414 | | - # Check if config has get method |
415 | | - if not hasattr(model.config, "get"): |
416 | | - return None |
417 | | - value = model.config.get(setting) |
418 | | - if value: |
419 | | - return value if case_sensitive else value.lower() |
420 | | - return None |
421 | | - except Exception as e: |
422 | | - logger.debug(f"Failed to get {setting} from model config: {e}") |
423 | | - return None |
424 | | - |
425 | | - # Replace problematic functions with safe versions |
426 | | - parse_model.catalog_name = safe_catalog_name |
427 | | - parse_model.file_format = safe_file_format |
428 | | - parse_model.location_path = safe_location_path |
429 | | - parse_model.location_root = safe_location_root |
430 | | - parse_model.table_format = safe_table_format |
431 | | - parse_model._get = safe_get |
432 | | - |
433 | | - logger.debug("Applied dbt-databricks 1.10.2 compatibility patch") |
434 | | - |
435 | | - except ImportError: |
436 | | - # parse_model module doesn't exist in older versions |
437 | | - pass |
438 | | - except Exception as e: |
439 | | - logger.debug(f"Failed to apply dbt-databricks compatibility patch: {e}") |
0 commit comments