Files

5.5 KiB
Raw Permalink Blame History

name, description, metadata
name description metadata
feishu-bitable 飞书多维表格(bitable)全流程操作:建表、字段/记录 CRUD、批量写入,含主字段改名与删字段防丢数据等踩坑要点。
author version
xf 1.0.0

飞书多维表格(Bitable)操作

创建/维护飞书多维表格的完整流程。基于 2026-08-03 创建「雨云 API 接口管理表」(437 条记录)实战验证。

前置条件

  • 应用已开通 bitable:app 权限(未开通会报 99991672 Access denied,需去开放平台申请)
  • 可复用 feishu-wiki-tools 的 init_token.py 获取 tenant_access_token:
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. 记录顺序对应:批量创建后按列表顺序取回,与源数据顺序一致,可用于按序回填/迁移。

完整示例(标准流程)

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,...