当前位置: 首页 > news >正文

飞书多维表格自动备份与清空

读取 A 表的全部记录 → 逐批写入 B 表 → 清空 A 表

#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ 飞书多维表格 通用备份清空工具 功能:将源表全部记录复制到目标表,然后清空源表 只需配置下方的 APP 凭证和表格 ID 即可运行 """ import time import requests # ============================================================ # 飞书配置(请改为你自己的信息) # ============================================================ FEISHU_APP_ID = "cli_xxxxxxxxxxxxx" # 替换为你的 App ID FEISHU_APP_SECRET = "your_app_secret" # 替换为你的 App Secret APP_TOKEN = "YOUR_APP_TOKEN" # 多维表格的 app_token SOURCE_TABLE_ID = "tblxxxxxxxxxxxxx" # 源表(将被复制并清空) TARGET_TABLE_ID = "tblyyyyyyyyyyyyy" # 目标表(备份目的地) # ============================================================ # 飞书 API 封装 # ============================================================ class FeishuBitable: def __init__(self, app_id, app_secret): self.app_id = app_id self.app_secret = app_secret self._token = None self._token_expire = 0 def _get_token(self): if self._token and time.time() < self._token_expire: return self._token url = "https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal" resp = requests.post(url, json={"app_id": self.app_id, "app_secret": self.app_secret}, timeout=15) if resp.status_code != 200: raise Exception(f"获取 token 失败,HTTP {resp.status_code}") result = resp.json() if result.get("code") != 0: raise Exception(f"获取 token 失败: {result}") self._token = result["tenant_access_token"] self._token_expire = time.time() + 7000 print("已获取 tenant_access_token") return self._token def get_all_records(self, table_id): """获取表中所有记录,返回原始 fields 字典列表(可直接用于创建)""" token = self._get_token() records = [] page_token = None while True: url = f"https://open.feishu.cn/open-apis/bitable/v1/apps/{APP_TOKEN}/tables/{table_id}/records/search" headers = {"Authorization": f"Bearer {token}", "Content-Type": "application/json"} body = {"page_size": 500} if page_token: body["page_token"] = page_token resp = requests.post(url, headers=headers, json=body, timeout=30) result = resp.json() if result.get("code") != 0: raise Exception(f"查询记录失败: {result}") data = result.get("data", {}) for item in data.get("items", []): records.append(item.get("fields", {})) if not data.get("has_more"): break page_token = data.get("page_token") print(f"从源表读取到 {len(records)} 条记录") return records def batch_create(self, table_id, records): """批量写入记录,records 为 fields 字典列表""" if not records: return token = self._get_token() url = f"https://open.feishu.cn/open-apis/bitable/v1/apps/{APP_TOKEN}/tables/{table_id}/records/batch_create" headers = {"Authorization": f"Bearer {token}", "Content-Type": "application/json"} # 一次最多创建 500 条,这里按 500 分批 for i in range(0, len(records), 500): batch = records[i:i+500] body = {"records": [{"fields": rec} for rec in batch]} resp = requests.post(url, headers=headers, json=body, timeout=60) result = resp.json() if result.get("code") != 0: raise Exception(f"批量写入失败: {result}") print(f" 已写入 {min(i+500, len(records))}/{len(records)} 条") print(f"成功备份全部 {len(records)} 条记录到目标表") def delete_all_records(self, table_id): """删除表中所有记录""" token = self._get_token() # 第一步:获取所有记录 ID record_ids = [] page_token = None while True: url = f"https://open.feishu.cn/open-apis/bitable/v1/apps/{APP_TOKEN}/tables/{table_id}/records/search" headers = {"Authorization": f"Bearer {token}", "Content-Type": "application/json"} body = {"page_size": 500} if page_token: body["page_token"] = page_token resp = requests.post(url, headers=headers, json=body, timeout=30) result = resp.json() if result.get("code") != 0: raise Exception(f"查询记录ID失败: {result}") data = result.get("data", {}) for item in data.get("items", []): record_ids.append(item["record_id"]) if not data.get("has_more"): break page_token = data.get("page_token") if not record_ids: print("源表已是空表,无需删除") return print(f"📋 共 {len(record_ids)} 条待删除") # 第二步:调用 batch_delete 删除 for i in range(0, len(record_ids), 500): batch = record_ids[i:i+500] del_url = f"https://open.feishu.cn/open-apis/bitable/v1/apps/{APP_TOKEN}/tables/{table_id}/records/batch_delete" headers = {"Authorization": f"Bearer {token}", "Content-Type": "application/json"} payload = {"records": batch} resp = requests.post(del_url, headers=headers, json=payload, timeout=30) result = resp.json() if result.get("code") != 0: raise Exception(f"删除失败: {result}") print(f" 已删除 {min(i+500, len(record_ids))}/{len(record_ids)} 条") print("源表已清空") # ============================================================ # 主流程:备份 + 清空 # ============================================================ def backup_and_clear(): print("=" * 50) print("开始执行:源表 → 目标表 备份 & 源表清空") feishu = FeishuBitable(FEISHU_APP_ID, FEISHU_APP_SECRET) # 1. 读取源表所有记录 records = feishu.get_all_records(SOURCE_TABLE_ID) if not records: print("源表无数据,跳过备份步骤") else: # 2. 写入目标表 feishu.batch_create(TARGET_TABLE_ID, records) # 3. 清空源表 feishu.delete_all_records(SOURCE_TABLE_ID) print("=" * 50) print("任务完成!") if __name__ == "__main__": backup_and_clear()
http://www.cnnetsun.cn/news/3216818.html

相关文章:

  • 从CBD到CID看杭州上城,未来十年AI+产业园区的样板间
  • 性能超过 GLM-5.1,混元 Hy3 两周限免!CodeBuddy 全系产品支持!
  • 50、<简单>数字方阵-对角线-2
  • fre:ac音频转换器:一站式解决所有音频格式转换需求
  • 瑞芯微RV1126B开发板(EASY-EAI-PI2) 人体关键点识别
  • B站视频秒变AI知识库:免费插件实现高效技术学习
  • 如何用Barlow字体为你的设计项目注入加州公路美学?
  • ARISTO Hand的远端过伸与刚柔传感协同机制解析
  • STM32G0B1RE与TPIS1S1385实现高精度人体存在检测方案
  • 终极数据恢复指南:如何使用TestDisk和PhotoRec找回丢失的分区和文件
  • DeepEval终极指南:3个技巧快速识别AI内容矛盾,提升文本一致性检测准确率
  • 循环经济再定调:一场从“扔掉”到“重生”的深刻革命
  • Simple Live跨平台直播聚合应用:告别频繁切换的终极解决方案
  • 新会上线!2026年工业工程与智能制造国际学术会议 (ICIEIM 2026)
  • 传统的SEO失效了?如何把微信群聊数据喂给AI,抢占下一代搜索红利
  • 别再跑腿了!无犯罪记录证明翻译线上办理全攻略(附费用与流程)
  • Gaze2Act:眼动引导的视觉语言动作联合建模框架
  • ECP5702+FP7208的RGBWY五路调光方案,不带内置电池,支持PD协议和多档电压输入
  • 标书查重太慢?万息投标查重单机版极速模式上线,纯文本文档秒级比对
  • 【GaussDB集群起不来的时候,我在cm_agent上卡了两个小时】
  • 双线突围!近零碳+绿色工厂,企业如何持续解锁“双碳”红利?
  • 告别RGB软件大战:一个开源工具统一所有设备灯光控制
  • 企业数据平台为什么必须从报表底座升级成AI运行底座?
  • 3分钟掌握Android自动打卡:DailyTask无人值守终极方案
  • 单阶段端到端强化学习实现人形机器人视觉驱动越障
  • 新版湿热加速试验来了!一文读懂GB/T 2423.34-2024元器件 “呼吸冻裂” 测试
  • 3步搞定漫画电子化:Kindle Comic Converter终极指南
  • 汽车零部件行业的质量管理软件有哪些?
  • 晚期癌症只能等?错!这种“绿色疗法”让很多患者重获生机
  • 苏州正规的画册设计公司哪家好