1. 项目背景与需求分析
1.1 需求场景还原
最近我在做一个数据清洗项目,需要定时从飞书多维表格中查询并删除过期记录。这个需求听起来很常见,但实际落地时发现坑不少。飞书多维表格的API文档虽然公开,但涉及查询、删除的细节处理,尤其是Python的集成方式,官方给的示例代码和实际生产环境差距不小。
我处理的场景是这样的:公司运营团队每天会往一个飞书多维表格里录入大量客户跟进记录,每条记录都有“创建时间”字段,我们需要定期清理掉超过30天且状态为“已关闭”的旧数据。一方面是为了提升表格的查询性能,另一方面也是合规要求——客户数据不能长期留存。
刚开始我打算用飞书内置的自动化流程来处理,但发现多维表格的自动化规则对删除操作支持有限,而且无法灵活控制删除条件。于是转向Python + 飞书开放API的方案,这是最直接、可控性最强的路径。
1.2 技术选型逻辑
为什么选择Python而不是其他语言?一是因为飞书官方提供了Python SDK(虽然版本更新慢,但基础功能够用),二是因为Python在处理数据清洗、批量操作这类任务上天然适合。更重要的是,我后续需要把这个删除脚本集成到定时任务中,Python的schedule库或者APScheduler都可以无缝对接。
查询和删除这两个操作,在飞书API中其实对应的是不同的接口。查询用的是“记录列表”接口,支持筛选条件;删除用的是“批量删除记录”接口,每次最多删除500条。这里有个关键点:删除前必须先查询出符合条件的记录ID,然后拿着ID去删除。所以整个流程可以拆解为:查询-获取ID列表-批量删除-验证删除结果。
1.3 权限与API基础准备
在开始写代码之前,有两件事必须先搞定。第一是飞书开放平台的App创建,第二是获取tenant_access_token。
飞书多维表格的API基于App的权限模型,你需要创建一个企业自建应用,然后申请“多维表格”相关的权限。具体来说,需要开通bitable:record:read(读取记录)和bitable:record:write(写入/删除记录)这两个权限。别小看这一步,很多人卡在权限申请上,因为飞书的应用权限审批流程比较繁琐,需要管理员手动确认。
获取token的方式是调用飞书身份验证接口,传入app_id和app_secret。这个token的有效期是2小时,所以代码里需要做缓存处理,避免每次请求都重新获取。我习惯用Python的time模块记录token的过期时间,到期前自动刷新。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 飞书多维表格API的核心机制详解
2.1 记录查询API的调用方式
飞书多维表格的查询接口是GET /open-apis/bitable/v1/apps/{app_token}/tables/{table_id}/records。这个接口支持分页、筛选和排序,但新人最容易踩的坑是筛选条件的写法。
筛选条件不是你想的SQL where语句,而是飞书自己定义的一套JSON格式。比如我要筛选“创建时间大于30天前并且状态为已关闭”,需要这样构造:
json复制{
"filter": {
"conjunction": "and",
"conditions": [
{
"field_name": "创建时间",
"operator": "isLess",
"value": "2024-01-01T00:00:00+08:00"
},
{
"field_name": "状态",
"operator": "is",
"value": "已关闭"
}
]
}
}
看到没,时间字段的筛选必须用ISO 8601格式,而且时区要明确。我一开始没注意时区问题,导致筛选出来的记录总是对不上,折腾了半天才发现是UTC和北京时间差了8小时。
2.2 分页查询的边界处理
飞书的查询接口默认一次返回20条记录,最大可以设置到500条。但你的删除操作可能涉及成千上万条记录,所以必须处理分页。
分页参数很简单:page_size 和 page_token。第一次请求不带page_token,返回结果里会包含has_more和next_page_token。你需要循环请求直到has_more为false。
这里有个性能优化点:查询接口每次请求都有一定的延迟,如果你一次只查20条,循环次数太多会很慢。我建议直接把page_size设成500,一次性拉满,减少请求次数。但注意,如果你的筛选条件比较复杂,返回500条数据可能需要2-3秒,要做好超时处理。
2.3 记录ID的获取与格式
查询返回的每条记录都有一个record_id字段,这个ID是字符串,格式类似recxxxxx。记住,这个ID是多维表格内部的唯一标识,删除操作必须用这个ID,而不能用其他的字段值。
我遇到过一种情况:多条记录的时间戳完全相同,导致查询结果顺序不稳定,翻页时可能出现重复或遗漏。飞书这个问题的官方解释是“默认不保证排序顺序”,解决方案是在查询时显式指定排序字段,哪怕你用_id排序也好。
3. Python代码实现:查询与删除全流程
3.1 环境准备与依赖安装
先列一下我用的Python环境:Python 3.10,依赖包只有requests和json,没有用飞书官方SDK。为什么不用官方SDK?因为官方SDK的封装太厚重,而且有些接口的版本对不上,出了问题排查起来反而麻烦。直接用requests调用REST API,自己控制所有细节,出了问题一眼就能看出来。
安装命令:
bash复制pip install requests
就这一个包就够了,其余的依赖都是标准库。
3.2 获取token的核心代码
token获取是基础操作,但必
