9.6 KiB
多数据源声明(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 时:
- Host ≥ 6.9.28
- 用户目录放置
data-sources.json(mysql 源 +connectionEnv) .env配置MYSQL_DSN(或你在 json 里声明的 env 名)requirements.txt含PyMySQL>=1.1.0(模板已声明)- 业务 DDL 同时支持 sqlite / mysql 分支(或仅部署 mysql)
- 抽测:数据管理 UI 与 CLI(如 list / create)读写同一库
- 见
../development/CHECKLIST.mdA6-16
选择飞书时:
- Host 已支持
feishu_bitable data-sources.json+.env凭证齐全columns收紧searchable/editable,结果链接用displayType: url- CLI / Action 与数据管理抽测同一
app_token+table_id - 见 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)幂等初始化元数据。