Airflow从v.2.2.2升级到v.2.7.2后DAG报错求助
问题背景
将Airflow从v2.2.2升级到v2.7.2后,DAG包内的相对导入失效,报错信息如下:
Broken DAG: [/opt/airflow/dags/foo_export/util.py] Traceback (most recent call last): File "
", line 228, in _call_with_frames_removed File "/opt/airflow/dags/foo_export/util.py", line 12, in from .constants import ERROR_LOG ImportError: attempted relative import with no known parent package
项目目录结构:
airflow ├── dags │ ├── foo_export │ ├── __init__.py │ ├── util.py │ ├── config.py │ ├── export.py │ ├── dags.py │ └── constants.py ├── airflow.cfg ├── logs ├── plugins
util.py中出错的导入语句:
from .constants import ERROR_LOG, PUBLICATION_DATE
原因分析
Airflow 2.7.x版本调整了DAG文件加载机制,不再默认将DAG子目录以完整Python包的方式导入。当Airflow加载util.py时,它被作为顶层模块处理,而非foo_export包的一部分,导致相对导入缺少父包上下文,触发报错。而v2.2.2的导入机制对包结构兼容性更强,允许这种相对导入方式。
解决方案
方案1:改用绝对导入(推荐)
利用Airflow默认将dags目录加入Python sys.path的特性,将相对导入替换为从包名开始的绝对导入:
# 修改util.py中的导入语句 from foo_export.constants import ERROR_LOG, PUBLICATION_DATE
方案2:确保包结构完整性(辅助验证)
确认foo_export目录下的__init__.py存在且无语法错误(空文件即可),保证目录被识别为合法Python包。此步骤需配合绝对导入使用,无法单独解决问题。
方案3:调整Airflow导入配置(可选)
若坚持使用相对导入,可尝试修改airflow.cfg中的core.dag_import_mode配置为lazy(默认可能为strict),但此方法不推荐——严格模式更符合Python导入规范,能避免潜在依赖问题:
[core] dag_import_mode = lazy
验证步骤
- 修改导入语句后保存文件
- 重启Airflow Scheduler和Webserver服务
- 查看Airflow UI中的DAG状态,确认报错消失
内容的提问来源于stack exchange,提问作者Phong

