Import Connection lazily in hooks to avoid cycles (#15361)

The current implementation imports Connection on import time, which
causes a circular import when a model class needs to reference a hook
class.

By applying this fix, the airflow.hooks package is completely decoupled
with airflow.models on import time, so model code can reference hooks.
Hooks, on the other hand, generally don't reference model classes.

Fix #15325.

(cherry picked from commit 7560316084)
This commit is contained in:
Tzu-ping Chung 2021-04-14 21:33:00 +08:00 коммит произвёл Ash Berlin-Taylor
Родитель 14c14dd2e2
Коммит cf2f7658a2
1 изменённых файлов: 8 добавлений и 4 удалений

Просмотреть файл

@ -18,12 +18,14 @@
"""Base class for all hooks"""
import logging
import warnings
from typing import Any, Dict, List
from typing import TYPE_CHECKING, Any, Dict, List
from airflow.models.connection import Connection
from airflow.typing_compat import Protocol
from airflow.utils.log.logging_mixin import LoggingMixin
if TYPE_CHECKING:
from airflow.models.connection import Connection # Avoid circular imports.
log = logging.getLogger(__name__)
@ -37,7 +39,7 @@ class BaseHook(LoggingMixin):
"""
@classmethod
def get_connections(cls, conn_id: str) -> List[Connection]:
def get_connections(cls, conn_id: str) -> List["Connection"]:
"""
Get all connections as an iterable, given the connection id.
@ -53,13 +55,15 @@ class BaseHook(LoggingMixin):
return [cls.get_connection(conn_id)]
@classmethod
def get_connection(cls, conn_id: str) -> Connection:
def get_connection(cls, conn_id: str) -> "Connection":
"""
Get connection, given connection id.
:param conn_id: connection id
:return: connection
"""
from airflow.models.connection import Connection
conn = Connection.get_connection_from_secrets(conn_id)
if conn.host:
log.info(