Files
skill-template/references/DATA_SOURCES.md
2026-11-01 16:30:46 +08:00

9.6 KiB
Raw Blame History

多数据源声明(SQLite / MySQL / 飞书多维表)

本文说明技能如何向匠厂宿主声明业务数据库,以及技能 CLI / Action 如何与宿主读写同一物理库(或同一飞书表)。

产品定位: 默认仍是本地 SQLite({skill_slug}.db)。需要多用户共享、集中运维或云库时,可显式声明 MySQL。需要以飞书多维表格为权威数据时,声明 feishu_bitable。UI / API 契约尽量一致;SQLite/MySQL 的 _jiangchang_* 展示元数据写在同一逻辑库中,飞书源用本文件的 columns 覆盖声明展示。

宿主版本:

能力 最低 Host
data-sources.json + MySQL ≥ 6.9.28
kind: feishu_bitable + columns 展示覆盖 以当前匠厂 Host 为准(task-plaza 等已落地;发布说明见 Host changelog)

完整参考实现:

  • MySQL:process-work-order @ v1.0.2
  • 飞书:业务技能 task-plaza(外包任务板)

何时用哪种后端

场景 推荐
单机、离线、小数据量、便携部署 SQLite(默认,不配声明文件亦可)
多用户共享、运维集中管库、与外部系统共库 MySQL 云库(显式 opt-in)
权威数据已在飞书多维表、多人在线协作 feishu_bitable(显式 opt-in)

硬规则:一个 sourceId 对应一个物理库 / 一张飞书业务表声明。 禁止双写、禁止 SQLite 与 MySQL / 飞书同步镜像。


文件位置

均在用户数据目录(不是安装包目录):

{JIANGCHANG_DATA_ROOT}/{JIANGCHANG_USER_ID}/{skill_slug}/
├── data-sources.json      # 声明式数据源(可选;见下)
├── .env                   # MYSQL_DSN / 飞书凭证等连接配置
└── {skill_slug}.db        # SQLite 模式下的本地库文件

安装/升级时,若用户目录尚无 data-sources.json 且技能包内有 assets/data-sources.example.json,宿主会复制一次示例(不覆盖已有文件)。

模板默认示例为 SQLite 显式声明(与自动扫描 {skill_slug}.db 等价)。改走 MySQL / 飞书时,请参照 assets/examples/ 下对应示例手工替换用户目录中的 data-sources.json,并在 .env 配置密钥。

若不需要声明式接入,可删除用户目录中的 data-sources.json,宿主恢复自动扫描 .db 文件。


data-sources.json 格式

根对象:

字段 类型 说明
version 1 固定为 1
sources 数组 至少一条数据源

每条 sources[]:

字段 必填 说明
id 是 英文标识,如 primary
kind 是 sqlite | mysql | feishu_bitable
displayName 否 侧栏展示名;多库时建议填写
path sqlite 必填 相对技能数据目录的路径;可用 {skillSlug} 占位
connectionEnv mysql 必填 .env 中 DSN 的环境变量名,如 MYSQL_DSN
appIdEnv / appSecretEnv / appTokenEnv feishu 必填 .env 中飞书应用与多维表 app_token 的变量名
tableIdEnv feishu 常用 .env 中业务表 table_id 的变量名(或宿主约定的等价字段)
columns 否 列展示覆盖(源无关;见下节)

SQLite 示例(模板默认)

见 ../assets/data-sources.example.json。

MySQL 示例

见 ../assets/examples/data-sources.mysql.example.json。

飞书多维表示例

见 ../assets/examples/data-sources.feishu_bitable.example.json。


columns 展示覆盖(源无关)

连接器先按后端生成列 schema(SQLite _jiangchang_columns / MySQL 元数据 / 飞书字段映射),再叠加 sources[].columns:

"columns": {
  "状态": { "editable": false, "searchable": true },
  "结果链接": { "displayType": "url", "editable": false, "searchable": false },
  "发单人": {
    "displayType": "userId",
    "editable": false,
    "formVisible": false,
    "defaultValueFrom": "currentUser.userId",
    "searchable": true
  },
  "平台": {
    "searchable": true,
    "optionsWhen": {
      "dependsOn": "任务类型",
      "map": { "文章发布": ["头条号", "搜狐号"], "视频发布": ["抖音", "视频号"] }
    }
  }
}
字段 类型 作用
displayType string 覆盖展示类型(如 url、textarea、userId、currency)
displayName string 覆盖列显示名
defaultValue string/number/boolean/null 新增表单默认值
defaultValueFrom string 从宿主会话预填:currentUser.userId / currentUser.username / currentUser.usernameOrUserId
optionsWhen object 依赖另一字段当前值过滤下拉:dependsOn + map
createable boolean false = 不进新增表单 / 不进 create payload
editable boolean false = 不进编辑表单 / 不进 update payload(状态机字段常用)
formVisible boolean false = 表单不展示但仍可按 createable/editable 写入(如静默 defaultValueFrom)
requiredOnCreate boolean 新增必填
searchable boolean 是否进列筛选与顶栏全局搜索(覆盖连接器默认)

与 _jiangchang_columns 的关系:

后端 主声明位置
SQLite / MySQL _jiangchang_columns(searchable / editable / display_type 等);data-sources.columns 可再覆盖
飞书 无 _jiangchang_* 表;以 data-sources.json 的 columns 为准覆盖飞书字段映射默认值

飞书连接器默认:明文与单选等常见字段可筛;技能用 searchable: true/false 收紧或放开筛选列(避免「全表可筛」噪音)。详见 SCHEMA.md「列筛选与全局搜索」与「display_type: url 外开」。


.env 与连接串

密钥写在用户 .env(或进程环境变量),不要写进 data-sources.json:

# MySQL 云库连接(不配则走本地 SQLite)
MYSQL_DSN=mysql://user:password@192.168.0.20:3306/your_database

# 飞书多维表(变量名须与 data-sources.json 中 *Env 一致)
FEISHU_APP_ID=cli_xxx
FEISHU_APP_SECRET=xxx
FEISHU_BITABLE_APP_TOKEN=bascnxxx
FEISHU_TASK_TABLE_ID=tblxxx

MySQL 格式:mysql:// 或 mysql2://,须含库名。注释写法须符合 ../development/CONFIG.md。

技能 Python 侧(SQLite/MySQL):scripts/db/backend.py 读取同一 MYSQL_DSN;有值则 resolve_backend() 为 mysql,否则 sqlite。飞书读写由技能自备 SDK / HTTP,与宿主连接器并行遵守同一张表、同一凭证 env。


技能代码职责

宿主 UI(数据管理)

宿主读取用户目录 data-sources.json + .env,经 Host 内置连接器访问库 / 飞书表。不依赖技能 connection.py。

CLI / Action / init-db

必须与宿主使用同一后端策略,否则会出现「UI 看云库、CLI 写本地 .db」的分裂。

模板已提供(SQLite / MySQL):

模块 作用
scripts/db/backend.py resolve_backend()、parse_mysql_dsn()
scripts/db/cursor_compat.py 统一 ? 占位符与 executescript
scripts/db/connection.py get_conn() 双分支;init_db() 幂等建 _jiangchang_*

业务表 DDL / 迁移仍在技能自己的 schema / init_db() 中按 conn.backend 分支处理(见工单参考实现)。飞书技能无本地业务 DDL,但仍须提供 health / Action 与宿主同一表。

可选:describe_active_store() 用于 health / 排障。


MySQL / 飞书 当前限制(Host)

MySQL:

  • 不支持 tableAdmin(建表/改表 UI)
  • 不支持 cellPresentation
  • 元数据与 CRUD 与 SQLite 路径一致

飞书:

  • 不支持本地式 tableAdmin / 随意改物理 DDL(字段以飞书后台为准)
  • 筛选/排序能力受飞书 API 约束;用 columns.searchable 控制筛选项
  • 附件 / 人员等字段依赖宿主映射的 displayType(如 attachment、userId)

表结构变更:SQLite/MySQL 由技能 init-db / 迁移负责;飞书在飞书后台改字段后,同步更新 columns 覆盖与技能读写字段名。


开发 Checklist(云库 / 飞书)

复制新业务技能并选择 MySQL 时:

  1. Host ≥ 6.9.28
  2. 用户目录放置 data-sources.json(mysql 源 + connectionEnv)
  3. .env 配置 MYSQL_DSN(或你在 json 里声明的 env 名)
  4. requirements.txt 含 PyMySQL>=1.1.0(模板已声明)
  5. 业务 DDL 同时支持 sqlite / mysql 分支(或仅部署 mysql)
  6. 抽测:数据管理 UI 与 CLI(如 list / create)读写同一库
  7. 见 ../development/CHECKLIST.md A6-16

选择飞书时:

  1. Host 已支持 feishu_bitable
  2. data-sources.json + .env 凭证齐全
  3. columns 收紧 searchable / editable,结果链接用 displayType: url
  4. CLI / Action 与数据管理抽测同一 app_token + table_id
  5. 见 CHECKLIST A6-17

与 SCHEMA / ACTIONS 的关系

  • SCHEMA.md:_jiangchang_* 适用于 SQLite/MySQL 已注册表;飞书用本文件 columns。url 外开、列筛选语义两边对齐。
  • ACTIONS.md:无 replaces 时宿主直写已注册数据源;状态机表常用 Policy 关裸编辑 + replaces: delete + visibleWhen。
  • CLI.md:init-db 对当前 active backend(sqlite/mysql)幂等初始化元数据。