# 导入与导出任务

使用传输任务在连接器来源与数据目录（Catalog）目标之间移动数据。导入和导出都是异步任务：创建请求返回后，应保存任务 ID，继续读取任务、运行和文件状态，不能把提交成功当作数据已经传输完成。

## 前提条件

- 已创建[连接器](connectors.md)、完成连接测试，并保存连接器 ID。
- 导入时已取得目标卷或表的 ID；导出时已取得源文件 ID 和完整路径。
- 当前身份具有读取源数据、写入目标资源和运行传输任务的权限。

## 导入任务如何工作

```text
选择连接器来源
→ 解析来源文件或结构化对象
→ 提交导入任务并保存 task_id
→ 查询任务和运行状态
→ 查看文件与行数结果
→ 只重试失败范围
```

导入任务使用 `/task` 路径族。连接器文件上传接口有时会直接创建任务并返回 `task_id`；显式创建任务则使用 `POST /task`。

## 创建导入任务

不同来源的 `source_config` 不同。下面展示当前创建接口的公共外层结构：

```bash
curl -X POST "$PRODUCT_API_BASE_URL/task" \
  -H "X-API-Key: $PRODUCT_API_KEY" \
  -H "X-Workspace-ID: $WORKSPACE_ID" \
  -H "Content-Type: application/json" \
  -d '{
    "source_connector_id": "<CONNECTOR_ID>",
    "config_type": <CONFIG_TYPE>,
    "name": "<IMPORT_TASK_NAME>",
    "volume_id": "<TARGET_VOLUME_ID>",
    "source_config": {
      "<SOURCE_CONFIG_FIELD>": "<SOURCE_CONFIG_VALUE>"
    }
  }'
```

| 字段 | 类型 | 必需 | 说明 |
| --- | --- | --- | --- |
| `source_connector_id` | string | 是 | 已保存并可访问的连接器 ID。 |
| `config_type` | integer | 是 | 导入配置类型。使用当前来源创建流程返回或要求的值。 |
| `name` | string | 否 | 任务名称。 |
| `volume_id` | string | 按任务 | 数据目录目标卷 ID。接口按字符串接收该值。 |
| `source_config` | object | 是 | 文件或结构化来源配置。字段取决于 `config_type`。 |

成功响应返回任务 ID：

```json
{
  "code": "OK",
  "msg": "OK",
  "data": {
    "task_id": "<IMPORT_TASK_ID>"
  }
}
```

保存 `task_id`，然后调用：

```bash
curl "$PRODUCT_API_BASE_URL/task/get?task_id=$IMPORT_TASK_ID" \
  -H "X-API-Key: $PRODUCT_API_KEY" \
  -H "X-Workspace-ID: $WORKSPACE_ID"
```

`data.task.status` 是导入任务面向调用方的数字状态：

| 值 | 状态 | 处理方式 |
| --- | --- | --- |
| `0` | 未知 | 读取错误摘要并停止自动推进。 |
| `1` | 活跃 | 继续查询导入任务或导入运行。 |
| `2` | 正在暂停 | 等待状态变化。 |
| `3` | 已暂停 | 可以修改、恢复或按权限删除。 |
| `4` | 已完成 | 检查文件和行数结果。 |
| `5` | 失败 | 检查 `error_code`、`error_summary` 和失败的导入任务文件。 |

导入运行通过 `GET /task/runs?task_id=...` 获取。导入运行自身使用另一套状态值：`1` 已创建、`2` 运行中、`3` 已完成、`4` 失败、`5` 已取消。不要把导入任务状态和导入运行状态混用。

导入任务文件结果通过 `GET /task/files?task_id=...` 获取。使用 `total_success`、`total_failed` 和 `files[].reason` 判断是否需要重试；只有部分导入任务文件失败时，将失败文件 ID 传给 `POST /task/retry`。

## 暂停、恢复和删除导入任务

| 请求 | 请求体 | 说明 |
| --- | --- | --- |
| `POST /task/pause` | `{"task_id":"<ID>"}` | 请求暂停任务；再次读取状态确认。 |
| `POST /task/resume` | `{"task_id":"<ID>"}` | 恢复已暂停任务。 |
| `POST /task/retry` | `{"task_id":"<ID>","ids":["<FILE_ID>"]}` | 重试指定失败的导入任务文件；空 `ids` 的行为应按当前接口验证。 |
| `POST /task/delete` | `{"task_id":"<ID>"}` | 删除允许删除的任务记录；不会自动撤销已写入数据。 |

## 创建和跟踪导出任务

导出任务使用 `/export/task` 路径族。创建请求需要目标连接器、目标类型、目标配置和源文件：

```bash
curl -X POST "$PRODUCT_API_BASE_URL/export/task/create" \
  -H "X-API-Key: $PRODUCT_API_KEY" \
  -H "X-Workspace-ID: $WORKSPACE_ID" \
  -H "Content-Type: application/json" \
  -d '{
    "task_name": "<EXPORT_TASK_NAME>",
    "connector_id": "<CONNECTOR_ID>",
    "connector_name": "<CONNECTOR_NAME>",
    "type": <EXPORT_TYPE>,
    "config": {
      "<TARGET_CONFIG>": {}
    },
    "files": [
      {
        "file_id": "<FILE_ID>",
        "full_path": ["<CATALOG>", "<DATABASE>", "<VOLUME>", "<FILE>"]
      }
    ]
  }'
```

创建成功后保存 `data.id`。使用下列接口读取进度：

| 方法与路径 | 结果 |
| --- | --- |
| `POST /export/task/info` | 任务详情、当前数字状态和文件统计 |
| `POST /export/task/files` | 文件状态与失败详情 |
| `GET /export/task/{task_id}/state` | `pending`、`running`、`failed` 和 `completed` 数量 |
| `POST /export/task/{task_id}/rerun` | 重试指定文件 |

导出任务状态为 `0` 待处理、`1` 运行中、`2` 已完成、`3` 失败。导出文件状态为 `0` 待处理、`1` 正在导出、`2` 已完成、`3` 失败、`4` 已下载。读取状态汇总时，`total` 应等于四个处理状态数量之和；已下载是文件详情状态，不单独出现在汇总计数中。

## 常见问题

| 现象 | 先检查 | 下一步 |
| --- | --- | --- |
| 创建任务失败 | 连接器 ID、来源配置、目标 ID 和当前权限 | 回到来源发现步骤，用服务端返回值重新构造请求。 |
| 请求成功但没有数据 | 任务状态、最新运行、文件计数和行数 | 等待终态；完成后再检查目标对象。 |
| 只有部分文件失败 | `files[].status`、`reason` 或 `details` | 只重试失败文件，不重新提交整个任务。 |
| 任务长期运行 | 运行 ID、更新时间和错误摘要 | 停止无界轮询，保留任务 ID 和最新状态用于排查。 |
| 删除后数据仍存在 | 目标数据目录或外部系统 | 任务删除不回滚已经写入或导出的数据，按目标系统规则清理。 |

## 下一步

- [检查数据目录中的目标文件](volumes-folders-files.md)
- [使用 SQL 验证目标表](../sql/execute-results.md)
- [查看工作流运行和数据血缘](../workflows-workitems-lineage/run-query-cancel.md)
