运行一个导入Airflow包的Python文件需要Airflow实例吗?

2 投票
2 回答
58 浏览
提问于 2025-04-14 18:07

我在使用Airflow时遇到了一个奇怪的导入问题。我想创建一个模块,其他人可以从中导入内容。同时,我也想对这个模块进行单元测试。不过,我发现只要从Airflow包中导入任何东西,它就会尝试运行Airflow。

举个例子:

# myfile.py
from airflow import DAG

print("Hello world")

然后用 python myfile.py 运行它,结果是:

(.venv) c:\Users\Jarro\Development\airflow-tryout-import>python myfile.py
WARNING:root:OSError while attempting to symlink the latest log directory
Traceback (most recent call last):
  File "c:\Users\Jarro\Development\airflow-tryout-import\myfile.py", line 1, in <module>
    from airflow import DAG
  File "C:\Users\Jarro\Development\airflow-tryout-import\.venv\Lib\site-packages\airflow\__init__.py", line 68, in <module>
    settings.initialize()
  File "C:\Users\Jarro\Development\airflow-tryout-import\.venv\Lib\site-packages\airflow\settings.py", line 559, in initialize
    configure_orm()
  File "C:\Users\Jarro\Development\airflow-tryout-import\.venv\Lib\site-packages\airflow\settings.py", line 237, in configure_orm
    raise AirflowConfigException(
airflow.exceptions.AirflowConfigException: Cannot use relative path: `sqlite:///C:\Users\Jarro/airflow/airflow.db` to connect to sqlite. Please use absolute path such as `sqlite:////tmp/airflow.db`.

除了错误本身,我更担心的是,似乎我无法从Airflow中导入东西,而不会引发一些副作用(比如数据库初始化)。我是不是走错了方向?有没有其他方法可以从Airflow中导入东西,而不会有这些副作用,比如为了类型提示的目的?

2 个回答

1

你可以在没有初始化 Airflow 的情况下进行导入,这样会自动创建一个默认的数据库,可能你已经注意到了。不过,Airflow 在 Windows 系统上并不好用,表现也不太稳定。

如果你主要是想进行类型检查或者注释,可能可以考虑使用 TYPE_CHECKING 这个块。

from __future__ import annotations

from typing import TYPE_CHECKING

if TYPE_CHECKING:
   from airflow.models.dag import DAG

3

这个问题发生是因为Python中的导入方式。你正在从airflow这个包中导入东西,而这个包里有一个__init__文件。

如果你查看这个文件,会发现里面有一段代码负责处理所有的airflow初始化工作。

__init__.py的第67到68行:
if not os.environ.get("_AIRFLOW__AS_LIBRARY", None):
settings.initialize()

如果你只是想像你说的那样导入一些东西用于类型提示,你可以把环境变量_AIRFLOW__AS_LIBRARY设置成任何值,这样就不会进行初始化了。

撰写回答