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

Airflow 2.7.1使用SFTP/SSH Operator批量复制远程文件至本地失败求助

解决Airflow 2.7.1批量远程文件复制到本地的报错问题

错误原因分析

你遇到的[Errno 21] Is a directory报错,核心是SFTPOperator对路径的识别逻辑不匹配:当你指定批量远程文件时,本地路径必须明确标记为目录,否则Operator会把它当成单个文件名处理,导致冲突。


方案一:修复SFTPOperator批量复制配置

SFTPOperator支持批量文件传输,但需要严格配置参数:

1. 通配符批量复制(推荐)

如果远程文件有统一命名规则,用通配符匹配,同时确保本地路径以斜杠结尾(明确是目录):

from airflow.providers.ssh.operators.sftp import SFTPOperator
from airflow.providers.ssh.hooks.ssh import SSHHook

# 替换为你的SSH连接ID
ssh_hook = SSHHook(ssh_conn_id="your_remote_ssh_conn")

sftp_batch_task = SFTPOperator(
    task_id="sftp_copy_batch_files",
    ssh_hook=ssh_hook,
    remote_filepath="/remote/server/path/*.txt",  # 用通配符匹配批量文件
    local_filepath="/mnt/d/New_folder/",  # 本地目录必须以/结尾
    operation="get",  # 明确是从远程拉取到本地(默认是put,本地推远程)
    create_intermediate_dirs=True,  # 自动创建不存在的本地目录
    dag=dag
)

2. 指定多个具体文件复制

如果需要复制的文件无统一规则,用PythonOperator结合SSHHook手动处理:

from airflow.operators.python import PythonOperator
from airflow.providers.ssh.hooks.ssh import SSHHook

def copy_specific_files():
    ssh_hook = SSHHook(ssh_conn_id="your_remote_ssh_conn")
    # 定义需要复制的远程文件列表
    remote_files = [
        "/remote/path/file1.csv",
        "/remote/path/subdir/file2.log",
        "/remote/path/file3.txt"
    ]
    local_dir = "/mnt/d/New_folder/"

    with ssh_hook.get_conn() as ssh_client:
        sftp_client = ssh_client.open_sftp()
        for remote_file in remote_files:
            # 提取文件名,拼接本地路径
            filename = remote_file.split("/")[-1]
            local_file_path = f"{local_dir}{filename}"
            sftp_client.get(remote_file, local_file_path)
        sftp_client.close()

python_copy_task = PythonOperator(
    task_id="copy_specific_remote_files",
    python_callable=copy_specific_files,
    dag=dag
)

方案二:用SSHOperator/BashOperator执行scp命令

之前scp失败大概率是命令参数错误,以下是正确写法:

1. 用BashOperator直接执行scp(Airflow运行在本地时推荐)

from airflow.operators.bash import BashOperator

bash_scp_task = BashOperator(
    task_id="bash_scp_batch",
    # 替换为你的远程SSH信息、文件路径
    bash_command="scp -i /path/to/your/private_key user@remote_host:/remote/path/*.txt /mnt/d/New_folder/",
    dag=dag
)

2. 用SSHOperator执行rsync(更稳定的批量复制)

rsync比scp更适合批量文件,支持断点续传:

from airflow.providers.ssh.operators.ssh import SSHOperator

rsync_task = SSHOperator(
    task_id="rsync_batch_copy",
    ssh_conn_id="your_remote_ssh_conn",
    # 远程执行rsync,将文件推送到本地(需本地开启SSH服务)
    command="rsync -avz /remote/path/*.txt user@local_host:/mnt/d/New_folder/",
    dag=dag
)

必做排查项

  • 权限检查:确认Airflow运行用户对/mnt/d/New_folder有读写权限,远程用户对目标文件有读取权限
  • 路径格式:Linux路径用/,Windows路径用D:\New_folder(若Airflow运行在原生Windows)
  • SSH连接验证:在Airflow UI中测试你的SSH连接ID,确保主机、端口、密钥/密码配置正确
  • 通配符有效性:在远程主机上手动执行ls /remote/path/*.txt,确认有匹配的文件

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 03:00:01