# 本地上传并创建导入任务

上传本地文件并创建导入任务。该接口使用 `multipart/form-data`；与连接器来源的 JSON 创建接口不同。成功响应返回任务 ID，但不表示所有文件已经写入目标位置或全部完成解析。

```text
POST https://moi.matrixorigin.cn/newmoi/connectors/upload
```

## 调用前准备

先选择数据形态和目标：

- **非结构化文件**写入数据卷。准备可写数据卷 ID，并通过 `VolumeID` 指定它。
- **结构化文件**写入数据表。当前创建页面只可选择 CSV、XLS 或 XLSX。先通过[上传文件](../connector-files/upload-file.md)取得 `conn_file_id`，再通过 `table_config` 指定已有目标表或新建目标表。结构化文件的数据行写入表，不写入 `VolumeID` 指定的数据卷。

当前创建页面的本地文件选择限制如下：

- 非结构化文件：一次最多选择 20 个文件，单个文件最大 200 MiB。可以选择文件或文件夹；选择文件夹时，文件夹中的每个文件均计入数量。
- 结构化文件：一次只能选择 1 个文件，单个文件最大 200 MiB；当前只允许 CSV、XLS 或 XLSX。

下方示例使用：

- `$AI_STUDIO_API_KEY`：实际个人访问令牌，通过 `X-API-Key` Header 传递。
- `$WORKSPACE_ID`：要创建任务的工作区 ID，通过 `X-Workspace-ID` Header 传递。

## 表单字段

本文中，类型后的 `[]` 表示数组，例如 `file[]` 表示文件数组。

| 字段 | 类型 | 是否必填 | 说明 |
| --- | --- | --- | --- |
| `file` | file[] | 条件必填 | 非结构化本地导入时上传一个或多个文件。每个文件使用同名字段 `file` 传递。结构化文件流程已先上传为临时文件时，不重复传该字段。 |
| `meta` | JSON array | 是 | 与上传文件顺序对应的来源信息。每项包含 `filename` 和 `path`；`path` 用于记录和匹配来源路径，不是目标数据卷目录。 |
| `VolumeID` | string | 条件必填 | 非结构化导入的目标数据卷 ID。请求没有目标目录字段，文件写入该数据卷；结构化文件导入不填写。 |
| `file_types` | JSON integer array | 否 | 允许处理的文件类型代码。代码与[查询文件列表](../connector-files/list-files.md)中的 `type` 相同。包含 `0`（其他）时不按文件类型筛选。 |
| `path_regex` | string | 否 | 仅处理 `meta.path` 匹配该正则表达式的文件。 |
| `unzip_keep_structure` | boolean string | 否 | 解压时是否保留目录结构，例如 `false`。当前创建页以扁平化方式处理压缩包。 |
| `dedup` | JSON object | 否 | 重复文件处理设置。对象包含 `by`（`name`、`md5` 或两者）和 `strategy`（`skip` 或 `overwrite`）。 |
| `table_config` | JSON object | 条件必填 | 结构化文件导入的目标表设置。可包含 `sheet_name`、`new_table`、`table_id`、`database_id`、`conn_file_ids`、`isColumnName`、`columnNameRow`、`rowStart`、`csv`、`conflict`、`existed_table`、`create_table` 和 `existed_table_opts`。已有表时填写 `new_table:false`、`table_id`、表头/起始行和 `existed_table` 列映射；新建表时填写 `new_table:true`、`database_id` 和 `create_table`。支持多工作表时使用 `multi_sheet:true` 和 `tables`。各字段含义见[创建连接器文件导入任务](create-import-task.md#请求体)。 |

## 请求示例

### 非结构化文件导入到数据卷

下例将本地文件上传到 `<VOLUME_ID>` 数据卷。路径正则作用于 `meta.path`，因此可以用它排除不需要的文件；它不控制数据卷内的目标目录。

```bash
curl -X POST "https://moi.matrixorigin.cn/newmoi/connectors/upload" \
  -H "X-API-Key: $AI_STUDIO_API_KEY" \
  -H "X-Workspace-ID: $WORKSPACE_ID" \
  -F 'file=@./manuals/product.pdf' \
  -F 'file=@./manuals/guide.docx' \
  -F 'VolumeID=<VOLUME_ID>' \
  -F 'meta=[{"filename":"product.pdf","path":"manuals/product.pdf"},{"filename":"guide.docx","path":"manuals/guide.docx"}]' \
  -F 'path_regex=^manuals/.*' \
  -F 'unzip_keep_structure=false' \
  -F 'dedup={"by":["name","md5"],"strategy":"skip"}'
```

### 本地 CSV 导入到已有数据表

先[上传文件](../connector-files/upload-file.md)取得 `<CONN_FILE_ID>`，再提交表配置。示例将第 1 行作为表头，从第 2 行开始读取数据，并把文件列映射到已有目标表。

```bash
curl -X POST "https://moi.matrixorigin.cn/newmoi/connectors/upload" \
  -H "X-API-Key: $AI_STUDIO_API_KEY" \
  -H "X-Workspace-ID: $WORKSPACE_ID" \
  -F 'meta=[{"filename":"orders.csv","path":"orders.csv"}]' \
  -F 'table_config={"new_table":false,"table_id":<TARGET_TABLE_ID>,"conn_file_ids":["<CONN_FILE_ID>"],"isColumnName":true,"columnNameRow":1,"rowStart":2,"csv":{"separator":","},"existed_table":[{"tableColumn":"<TARGET_COLUMN>","column":"<FILE_COLUMN>","col_num_in_file":1}],"existed_table_opts":{"method":"append"}}'
```

## 成功响应

当响应中的 `code` 为 `OK` 时，任务已受理。

```json
{
  "code": "OK",
  "msg": "OK",
  "data": {
    "task_id": "task_01",
    "file_ids": ["file_01"],
    "success": true,
    "message": "OK",
    "results": [
      {"success": true, "message": "OK"}
    ]
  }
}
```

响应字段如下。

| 字段 | 类型 | 说明 |
| --- | --- | --- |
| `code` | string | 成功时为 `OK`。 |
| `msg` | string | 成功时为 `OK`。 |
| `data.task_id` | string | 创建的导入任务 ID。 |
| `data.file_ids` | string（字符串数组） | 本次新上传并成功处理的文件 ID；结构化临时文件流程中可能为空。 |
| `data.success` | boolean | 请求是否创建成功。 |
| `data.message` | string | 处理结果说明。 |
| `data.results` | object（对象数组） | 按文件返回的处理结果。每项包含 `success` 和 `message`。 |

## 错误响应

```json
{
  "code": "ErrParamInvalid",
  "msg": "invalid upload parameters",
  "data": null
}
```

### 常见 HTTP 错误

```{list-table}
:header-rows: 1
:widths: 12 25 30 33

* - HTTP 状态码
  - 错误代码
  - 常见原因
  - 建议操作
* - `400`
  - `ErrParamInvalid`
  - multipart 表单无效，或 `VolumeID`、`table_config`、路径正则不符合要求。
  - 检查字段名、JSON 字符串、目标资源 ID 和正则表达式。
* - `403`
  - `ErrForbidden`
  - 调用者无权向目标数据卷或目标表写入数据。
  - 检查工作区、数据卷和数据表授权。
* - `200`
  - `ErrServer`
  - 服务未能创建或调度任务。
  - 同时检查 HTTP 状态和 `code`，稍后重试或查询任务状态。
```

## 后续操作

记录 `data.task_id`。使用该 ID [查询任务详情](get-import-task.md)确认目标、状态和处理统计；必要时再[查询任务文件](list-import-task-files.md)或[查询运行记录](list-import-task-runs.md)。
