|  | 
| 16 | 16 | from typing_extensions import TypeAlias | 
| 17 | 17 | import inspect | 
| 18 | 18 | 
 | 
|  | 19 | +import dlt | 
| 19 | 20 | from dlt.common import logger | 
| 20 | 21 | from dlt.common.configuration.specs.base_configuration import BaseConfiguration | 
| 21 | 22 | from dlt.common.normalizers.naming import NamingConvention | 
| 22 | 23 | from dlt.common.configuration import resolve_configuration, known_sections | 
| 23 | 24 | from dlt.common.destination.capabilities import DestinationCapabilitiesContext | 
| 24 | 25 | from dlt.common.destination.exceptions import ( | 
| 25 |  | -    DestinationTypeResolutionException, | 
| 26 | 26 |     InvalidDestinationReference, | 
| 27 | 27 |     UnknownDestinationModule, | 
| 28 | 28 | ) | 
| 29 |  | -from dlt.common.destination.client import ( | 
| 30 |  | -    DestinationClientConfiguration, | 
| 31 |  | -    JobClientBase, | 
| 32 |  | -    DestinationTypeConfiguration, | 
| 33 |  | -) | 
|  | 29 | +from dlt.common.destination.client import DestinationClientConfiguration, JobClientBase | 
| 34 | 30 | from dlt.common.runtime.run_context import get_plugin_modules | 
| 35 | 31 | from dlt.common.schema.schema import Schema | 
| 36 | 32 | from dlt.common.typing import is_subclass | 
| @@ -272,37 +268,40 @@ def from_reference( | 
| 272 | 268 |                 ) | 
| 273 | 269 |             return ref | 
| 274 | 270 | 
 | 
| 275 |  | -        # If destination_name is not provided and ref does not contain dots | 
| 276 |  | -        # try to resolve named destination with destination type | 
| 277 |  | -        named_dest_error = None | 
| 278 |  | -        if not destination_name and "." not in ref: | 
|  | 271 | +        # If destination name is provided or ref is a module ref | 
|  | 272 | +        # don't attempt to resolve as named destination | 
|  | 273 | +        if destination_name or "." in ref: | 
|  | 274 | +            return DestinationReference.from_reference( | 
|  | 275 | +                ref, credentials, destination_name, environment, **kwargs | 
|  | 276 | +            ) | 
|  | 277 | + | 
|  | 278 | +        # First, try to resolve as a named destination with configured type | 
|  | 279 | +        destination_type: str = dlt.config.get(f"destination.{ref}.destination_type") | 
|  | 280 | +        if destination_type: | 
| 279 | 281 |             try: | 
| 280 | 282 |                 return DestinationReference.from_name( | 
| 281 |  | -                    credentials=credentials, | 
|  | 283 | +                    destination_type=destination_type, | 
| 282 | 284 |                     destination_name=ref, | 
|  | 285 | +                    credentials=credentials, | 
| 283 | 286 |                     environment=environment, | 
| 284 | 287 |                     **kwargs, | 
| 285 | 288 |                 ) | 
| 286 |  | -            except Exception as e: | 
| 287 |  | -                named_dest_error = e | 
|  | 289 | +            except Exception: | 
|  | 290 | +                pass | 
| 288 | 291 | 
 | 
| 289 |  | -        # Fallback to shorthand type reference | 
|  | 292 | +        # Then, try to resolve as a shorthand destination ref | 
| 290 | 293 |         try: | 
| 291 |  | -            dest_ref = DestinationReference.from_reference( | 
|  | 294 | +            return DestinationReference.from_reference( | 
| 292 | 295 |                 ref, credentials, destination_name, environment, **kwargs | 
| 293 | 296 |             ) | 
| 294 |  | -            return dest_ref | 
| 295 |  | -        except Exception as e: | 
| 296 |  | -            if named_dest_error is None: | 
| 297 |  | -                # Only direct type resolution was attempted, raise original error | 
| 298 |  | -                raise e | 
| 299 |  | -            else: | 
| 300 |  | -                # Both resolution methods failed, use comprehensive exception | 
| 301 |  | -                raise DestinationTypeResolutionException( | 
| 302 |  | -                    ref=ref, | 
| 303 |  | -                    type_resolution_error=e, | 
| 304 |  | -                    named_dest_error=named_dest_error, | 
| 305 |  | -                ) | 
|  | 297 | +        except UnknownDestinationModule as e: | 
|  | 298 | +            raise UnknownDestinationModule( | 
|  | 299 | +                ref=e.ref, | 
|  | 300 | +                qualified_refs=e.qualified_refs, | 
|  | 301 | +                traces=e.traces, | 
|  | 302 | +                destination_type=destination_type, | 
|  | 303 | +                named_dest_attempted=True, | 
|  | 304 | +            ) from e.__cause__ | 
| 306 | 305 | 
 | 
| 307 | 306 | 
 | 
| 308 | 307 | class DestinationReference: | 
| @@ -415,31 +414,23 @@ def from_reference( | 
| 415 | 414 |     @classmethod | 
| 416 | 415 |     def from_name( | 
| 417 | 416 |         cls, | 
|  | 417 | +        destination_type: str, | 
| 418 | 418 |         destination_name: str, | 
| 419 | 419 |         credentials: Optional[Any] = None, | 
| 420 | 420 |         environment: Optional[str] = None, | 
| 421 | 421 |         **kwargs: Any, | 
| 422 | 422 |     ) -> Optional[AnyDestination]: | 
| 423 |  | -        resolved_config = resolve_configuration( | 
| 424 |  | -            DestinationTypeConfiguration(), | 
| 425 |  | -            sections=(known_sections.DESTINATION, destination_name), | 
|  | 423 | +        """Instantiate destination from a destination type and name. | 
|  | 424 | +        This method creates a named destination by using the destination type | 
|  | 425 | +        as a factory and instantiating it with the provided destination name. | 
|  | 426 | +        """ | 
|  | 427 | +        return DestinationReference.from_reference( | 
|  | 428 | +            ref=destination_type, | 
|  | 429 | +            credentials=credentials, | 
|  | 430 | +            destination_name=destination_name, | 
|  | 431 | +            environment=environment, | 
|  | 432 | +            **kwargs, | 
| 426 | 433 |         ) | 
| 427 |  | -        destination_type = resolved_config.destination_type | 
| 428 |  | -        try: | 
| 429 |  | -            return DestinationReference.from_reference( | 
| 430 |  | -                ref=destination_type, | 
| 431 |  | -                credentials=credentials, | 
| 432 |  | -                destination_name=destination_name, | 
| 433 |  | -                environment=environment, | 
| 434 |  | -                **kwargs, | 
| 435 |  | -            ) | 
| 436 |  | -        except UnknownDestinationModule as e: | 
| 437 |  | -            raise UnknownDestinationModule( | 
| 438 |  | -                ref=e.ref, | 
| 439 |  | -                qualified_refs=e.qualified_refs, | 
| 440 |  | -                traces=e.traces, | 
| 441 |  | -                from_name=True, | 
| 442 |  | -            ) | 
| 443 | 434 | 
 | 
| 444 | 435 |     @staticmethod | 
| 445 | 436 |     def normalize_type(destination_type: str) -> str: | 
|  | 
0 commit comments