You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Airflow BashOperator执行SQLPlus脚本报Error 45问题求助

问题:Airflow BashOperator执行SQL*Plus脚本时报Error 45(非本地文件系统不兼容)

命令行直接运行bash脚本可正常执行SQLPlus命令,但通过Airflow DAG的BashOperator调用时,触发SQLPlus初始化错误Error 45,提示信息:

使用了与SQL Plus不兼容的非本地文件系统


核心原因

Airflow的BashOperator默认工作目录通常是Airflow的dags目录,如果该目录挂载在NFS、S3挂载目录等非本地文件系统上,SQL*Plus初始化时需要读写本地临时文件,无法在非本地文件系统完成这类操作,就会抛出该错误。


解决方案

方案1:指定BashOperator工作目录为本地路径

在BashOperator中通过cwd参数指定本地临时目录,让SQL*Plus在本地文件系统环境下执行:

修改后的DAG代码示例:

from airflow import DAG
from airflow.operators.bash import BashOperator
from datetime import datetime
import os

default_args = {
    'owner': 'airflow',
    'start_date': datetime(2024, 1, 1),
}

with DAG('sqlplus_dag', default_args=default_args, schedule_interval='@daily') as dag:
    run_sql_script = BashOperator(
        task_id='run_sql_script',
        # 先创建临时目录再执行脚本
        bash_command='mkdir -p /tmp/airflow_sqlplus_temp && /path/to/your/script.sh',
        # 指定本地工作目录
        cwd='/tmp/airflow_sqlplus_temp'
    )

同时修改bash脚本,把SQL文件复制到本地临时目录后再执行:

#!/bin/bash
# 把SQL脚本复制到本地临时目录
cp /path/to/your/sql_script.sql /tmp/airflow_sqlplus_temp/
# 执行SQL*Plus命令
sqlplus username/password@db @sql_script.sql
# 清理临时文件
rm /tmp/airflow_sqlplus_temp/sql_script.sql

方案2:设置SQL*Plus临时目录环境变量

SQL*Plus会读取TMP或TEMP环境变量作为临时文件存储路径,直接在BashOperator中指定这两个变量为本地路径:

DAG代码示例:

run_sql_script = BashOperator(
    task_id='run_sql_script',
    bash_command='/path/to/your/script.sh',
    # 注入本地临时目录环境变量,保留原有系统环境变量
    env={
        'TMP': '/tmp/airflow_sqlplus',
        'TEMP': '/tmp/airflow_sqlplus',
        **os.environ
    }
)

在bash脚本开头添加目录创建命令:

mkdir -p /tmp/airflow_sqlplus

更优任务编写方式:使用OracleOperator替代BashOperator

如果Airflow环境已安装apache-airflow-providers-oracle插件,建议直接用OracleOperator执行SQL,彻底避开SQL*Plus的文件系统依赖问题,同时更符合Airflow的任务编排规范:

示例代码:

from airflow import DAG
from airflow.providers.oracle.operators.oracle import OracleOperator
from datetime import datetime

default_args = {
    'owner': 'airflow',
    'start_date': datetime(2024, 1, 1),
}

with DAG('oracle_sql_dag', default_args=default_args, schedule_interval='@daily') as dag:
    run_oracle_sql = OracleOperator(
        task_id='run_oracle_sql',
        oracle_conn_id='your_oracle_connection',  # 提前在Airflow UI配置Oracle连接
        sql='/path/to/your/sql_script.sql'
        # 也可以直接写SQL语句:sql="INSERT INTO your_table VALUES (1, 'test');"
    )

这种方式通过Python的cx_Oracle库直接连接Oracle执行SQL,无需依赖SQL*Plus,日志输出更清晰,任务状态监控也更方便。

内容的提问来源于stack exchange,提问作者Scott Luisi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 05:42:18