102 lines
5.5 KiB
Markdown
102 lines
5.5 KiB
Markdown
---
|
||
name: "feishu-bitable"
|
||
description: "飞书多维表格(bitable)全流程操作:建表、字段/记录 CRUD、批量写入,含主字段改名与删字段防丢数据等踩坑要点。"
|
||
metadata:
|
||
author: xf
|
||
version: "1.0.0"
|
||
---
|
||
|
||
# 飞书多维表格(Bitable)操作
|
||
|
||
创建/维护飞书多维表格的完整流程。基于 2026-08-03 创建「雨云 API 接口管理表」(437 条记录)实战验证。
|
||
|
||
## 前置条件
|
||
|
||
- 应用已开通 `bitable:app` 权限(未开通会报 `99991672 Access denied`,需去开放平台申请)
|
||
- 可复用 `feishu-wiki-tools` 的 `init_token.py` 获取 tenant_access_token:
|
||
|
||
```bash
|
||
cd ~/.openclaw/workspace/skills/feishu-wiki-tools
|
||
python3 - <<'EOF'
|
||
import json, subprocess, requests
|
||
r = subprocess.run(['python3', 'scripts/init_token.py'], capture_output=True, text=True)
|
||
token = json.loads(r.stdout)['token']
|
||
h = {'Authorization': f'Bearer {token}', 'Content-Type': 'application/json'}
|
||
EOF
|
||
```
|
||
|
||
## 核心 API
|
||
|
||
| 操作 | 端点 | 说明 |
|
||
|------|------|------|
|
||
| 创建应用 | `POST /open-apis/bitable/v1/apps` | body `{name}`,返回 `app_token` + `default_table_id` |
|
||
| 建字段 | `POST /apps/{APP}/tables/{TBL}/fields` | body `{field_name, type}` |
|
||
| 改字段 | `PUT /apps/{APP}/tables/{TBL}/fields/{fid}` | **改主字段名必须带 `type` + `ui_type`** |
|
||
| 删字段 | `DELETE /apps/{APP}/tables/{TBL}/fields/{fid}` | ⚠️ 连带删除该列全部数据 |
|
||
| 列字段 | `GET /apps/{APP}/tables/{TBL}/fields?page_size=100` | 响应含 `is_primary` 标记 |
|
||
| 批量写入 | `POST /apps/{APP}/tables/{TBL}/records/batch_create` | body `{records:[{fields:{...}}]}`,≤100/批稳妥 |
|
||
| 批量更新 | `POST /apps/{APP}/tables/{TBL}/records/batch_update` | 同上 |
|
||
| 批量删除 | `POST /apps/{APP}/tables/{TBL}/records/batch_delete` | body `{records:[record_id...]}` |
|
||
| 列表分页 | `GET /apps/{APP}/tables/{TBL}/records?page_size=500&page_token=...` | 循环直到 `has_more=false` |
|
||
| 搜索统计 | `POST /apps/{APP}/tables/{TBL}/records/search` | body `{page_size:1}`,`data.total` 拿总数 |
|
||
|
||
## 字段类型速查
|
||
|
||
`1=Text`、`3=SingleSelect`、`5=DateTime`、`17=Attachment`
|
||
|
||
## ⚠️ 建表标准流程(顺序很重要)
|
||
|
||
1. **创建应用** → 拿到 `app_token`、`default_table_id`
|
||
2. **先清默认行**:新建表自带 10 条空记录,`batch_delete` 删掉
|
||
3. **先删默认字段**:自带「文本/单选/日期/附件」4 列中,**「文本」是主字段删不掉**,其余 3 个直接删掉
|
||
4. **改造主字段**:把删不掉的主字段「文本」改造成自己需要的列(如「接口路径」)——`PUT /fields/{fid}`,body 必须带 `type` + `ui_type`(如 `{"field_name":"接口路径","type":1,"ui_type":"Text"}`)
|
||
5. **添加剩余自己的字段**:`POST /fields` 逐个建(方法、摘要、参数…)
|
||
6. **写入数据**:`batch_create` 分批(100/批 + `time.sleep(0.3)` 限速)
|
||
7. **验证**:`records/search` 拿 total 核对 == 写入条数
|
||
|
||
## 🕳️ 踩坑记录(全部实战踩过)
|
||
|
||
1. **主字段(Primary Field)不可删除**(报 `1254046 The Primary Field cannot be deleted`)。只能改名复用:`PUT /fields/{fid}`,**body 必须带 `type` + `ui_type`**(如 `{"field_name":"接口路径","type":1,"ui_type":"Text"}`),否则报 `99992402 field validation failed`。所以正确姿势是**先把它改造成自己的字段**,而不是新建一个同义字段再删旧的。
|
||
2. **删字段 = 删数据**:删除字段会把该列所有记录值一起删掉,不可恢复。删之前必须:① 确认本地有备份,或 ② 先把数据迁到别的字段(batch_update 逐批迁移后再删)。
|
||
3. **改名失败后不要连锁删字段**:字段改名失败(99992402)时,后续依赖新字段名的操作会全部失败(1254045 field not found),此时若顺手把旧字段删了会造成数据丢失。改名前先验证字段存在。
|
||
4. **批量写入上限**:官方上限 500/次,实测 100/批最稳;批量间加 0.3s 间隔避免限流。
|
||
5. **记录顺序对应**:批量创建后按列表顺序取回,与源数据顺序一致,可用于按序回填/迁移。
|
||
|
||
## 完整示例(标准流程)
|
||
|
||
```python
|
||
APP = 'xxx' # 创建返回的 app_token
|
||
TBL = 'xxx' # default_table_id
|
||
h = {'Authorization': f'Bearer {token}', 'Content-Type': 'application/json'}
|
||
|
||
# 1. 读默认空记录并删除(10 条自带空行)
|
||
recs = ... # GET records 分页拉全
|
||
empty = [r['record_id'] for r in recs if not r['fields']]
|
||
requests.post(f'.../records/batch_delete', headers=h, json={'records': empty})
|
||
|
||
# 2. 删默认字段(跳过 is_primary 的「文本」)
|
||
for f in fields:
|
||
if not f.get('is_primary') and f['field_name'] in ('单选','日期','附件'):
|
||
requests.delete(f'.../fields/{f["field_id"]}', headers=h)
|
||
|
||
# 3. 改造主字段「文本」→ 自己的字段
|
||
requests.put(f'.../fields/{primary_fid}', headers=h,
|
||
json={'field_name': '接口路径', 'type': 1, 'ui_type': 'Text'})
|
||
|
||
# 4. 添加剩余字段
|
||
for name, ftype in [('方法',3),('接口摘要',1),('参数',1)]:
|
||
requests.post(f'.../apps/{APP}/tables/{TBL}/fields', headers=h,
|
||
json={'field_name': name, 'type': ftype})
|
||
|
||
# 5. 批量写数据
|
||
rows = [...] # [{fields: {...}}, ...]
|
||
for i in range(0, len(rows), 100):
|
||
requests.post(f'.../records/batch_create', headers=h, json={'records': rows[i:i+100]})
|
||
time.sleep(0.3)
|
||
```
|
||
|
||
## 关联
|
||
|
||
- `feishu-wiki-tools` — 知识库/docx 写入,本 skill 专注 bitable 多维表格
|
||
- 权限申请链接格式:`https://open.feishu.cn/app/{app_id}/auth?q=bitable:app,...`
|