Commit 0634fb08 authored by Data Governance Dev's avatar Data Governance Dev

feat(skill): 新增 find-field —— 跨库盘点字段 + 行数 + 视图溯源

新建 .claude/skills/find-field/:
- SKILL.md:调用方式 / 参数 / 输出格式 / 6 条踩坑 / 安全约束
- scripts/find_field.py:从 web3 connection_preset 读连接,三方言
  (MySQL/达梦/Oracle) 扫列名 + COUNT(*) + USER_DEPENDENCIES 溯源 V_* 视图

安全:
- 数据库连接只能选 web3 已存的(13 个预设),不允许临时输入密码
- 只读 SELECT,不发 DML(CLAUDE.md 原则)

附带 web3/tests/_probe_gjj80_bankcard.py:
GJJ80 一次性探测脚本,作为本次 skill 命名的原型被保留作历史对照。
SKILL.md 里点名「已被本 skill 取代」,但保留 git 历史。

验证:find-field huanggang-gjj 银行卡号 → 与一次性脚本结果完全一致
(V_JCFX_DWXX 11768 + V_JCFX_GRXX 567523 + 基表 GJ_DWXX/GJ_GRXX)
parent b0b09f46
---
name: find-field
description: 在 web3 已存储的数据库连接里,按关键字扫字段名 + 取行数 + 视图溯源。专为「跨库盘点字段 / 数据量」场景设计,例如「GJJ80 哪些表有银行卡号」「mysql.smart-build 里哪些表带 phone 字段」。数据库连接只能选 web3 里存的(不允许临时输入),保证安全 + 可审计。
metadata:
argument-hint: "<db-alias> <keyword> [more keywords ...]"
allowed-tools: Bash
---
# find-field —— 跨库盘点字段 + 行数
## 何时使用
- 用户说「找一下 XX 库里哪些表有 YY 字段」「YY 库有多少数据」
- 建数据质量任务前盘点字段位置 + 数据量
- 跨库对比(同一字段名在多个数据库里的分布)
- 视图溯源(V_* 视图背后是哪张基表 + 基表行数)
**适用数据库**:MySQL / 达梦 / Oracle 三种方言都支持,统一走 web3 的 `DBConnection` 封装。
## 调用方式
**先通过 Bash 调用脚本**,把脚本输出原样回给用户(脚本输出已经按表格排好)。
```bash
# Windows + Git Bash / PowerShell / cmd 通用
python .claude/skills/find-field/scripts/find_field.py --db <db-alias> --keywords <kw1> [kw2 ...]
# 只列已存储的连接(用户没指定时,先 --list 拿清单让用户挑)
python .claude/skills/find-field/scripts/find_field.py --list
# Windows cmd / PowerShell 中文乱码 → 加 PYTHONUTF8=1
set PYTHONUTF8=1
python .claude/skills/find-field/scripts/find_field.py --db huanggang-gjj --keywords 银行卡号
```
## 参数
| 参数 | 必填 | 说明 |
|---|---|---|
| `--db` | 是(除非 `--list`) | web3 已存储的连接别名。允许:①精确 `name`(如 `huanggang-gjj`);②模糊 `display`(如「黄冈公积金」);找不到时报错并列出所有 |
| `--keywords` | 是(除非 `--list`) | 1+ 个列名关键字,大小写不敏感,子串匹配(`LIKE %kw%`)。中英文都行 |
| `--list` | 否 | 只列出 web3 已存的连接,不查库 |
| `--db-path` | 否 | 覆盖 web3.db 路径(默认读 `web3.backend.config.DB_PATH`,可用环境变量 `WEB3_DB_PATH` 改) |
## 输出格式
```
================================================================================
DB : <display>(<db_type>)
URI : <db_type>://<user>@<host>:<port>/<database>
关键字 : [<kw1>, <kw2>, ...]
================================================================================
[1/3] 扫字段...
→ 命中 N 个(表, 列)
[2/3] 取每张表行数...
================================================================================
结果汇总
================================================================================
表名 行数 列名 类型 可空 表注释
------------------------------------------------------------------------------------------------------------------------
V_JCFX_DWXX 11,768 银行账号 VARCHAR2(30) Y
V_JCFX_GRXX 567,523 银行账号 VARCHAR2(30) Y
------------------------------------------------------------------------------------------------------------------------
匹配表数: 2 匹配列数: 2 行数总计: 579,291
[3/3] 视图依赖溯源...
VIEW V_JCFX_DWXX → 引用:
BASE TABLE GJJ80.GJ_DWXX 行数=11,768
VIEW V_JCFX_GRXX → 引用:
BASE TABLE GJJ80.GJ_GRXX 行数=567,523
```
三段:
1. **结果汇总**:每个(表, 列)一行,行数就是 COUNT(*),按表聚合展示
2. **视图依赖溯源**(仅 Oracle/达梦):命中以 `V_` 开头的视图时,`USER_DEPENDENCIES` 找背后基表 + 行数
3. 子串匹配会带干扰项(如「账号」会同时命中「银行账号/单位账号/个人账号」),用户在表格里挑真的那张
## 安全约束
- **只能用 web3 里已存的连接**:脚本启动先读 `connection_preset`,找不到 --db 报错并列出全部,不允许临时输入 host/port/密码
- **只读**:用 `DBConfig` + `DBConnection`,只跑 SELECT,没碰 DML(项目原则 CLAUDE.md「永远不要使用数据操作语句」)
- **密码脱敏**:脚本输出不打印 password(DBConfig 里也不会带出来);URI 行只打 `user@host:port/database`
## 调用流程(Claude 该怎么做)
1. 用户调用 skill,参数格式:`<db-alias> <keyword> [<keyword> ...]`
2. **如果用户没给 `--db`**:先跑 `--list` 拿连接清单,列出 `name` / `display` 给用户挑,等用户回
3. **如果用户给的 db 名字找不到**:脚本会自己报错并列出全部 13 个连接 → 把脚本错误输出原样回给用户,让他/她挑
4. 拿到正确 --db 和 --keywords 后,跑脚本 → 把输出原样回给用户(不要二次解析、不要省略表格、不要自己写总结)
5. **可选**:跑完后帮用户做一个 1~2 行的中文要点总结(命中几表 / 哪张最大 / 干扰项提示),但表格内容必须照搬脚本输出
## 踩坑
1. **Windows cmd / PowerShell 中文乱码**:cmd 默认 GBK,脚本输出里中文是 UTF-8 → 表格列对不齐。
解决:调用前 `set PYTHONUTF8=1`(cmd)或 `$env:PYTHONUTF8=1`(PowerShell),或直接用 Git Bash。
2. **Oracle thin 模式连不上老 Oracle(11g 及以下)**:脚本读 `connection_preset.oracle_client_dir` 自动切 thick 模式,**不需要用户配置**。
3. **db_adapter 归一化列名为小写**:脚本内访问 dict 都用 lowercase key(`r["table_name"]` 不是 `r["TABLE_NAME"]`),跟 web3 后端一致
4. **大量「账号/帐号」类干扰项**:「账号」做关键字会同时命中「银行账号」「单位账号」「社保账号」「个人账号」等——子串匹配通病,靠人工看表注释/列注释筛;模糊关键字越短,干扰越多
5. **视图行数 = COUNT(*)**:有些 V_* 是带 WHERE 的视图,行数不等于底层基表行数;脚本默认报视图行数,基表行数在「依赖溯源」段再单独打
6. **GJJ80 类用户视图权限有限**:`ALL_DEPENDENCIES` 通常查不到,脚本默认走 `USER_DEPENDENCIES`(用户视角),基表不在当前 schema 时会 0 行——这是预期行为
## 实现要点
- 路径:`scripts/find_field.py`(独立脚本,sys.path 注入 `<project_root>` 后 import `web3.backend`)
- 数据字典查询走方言分流:
- Oracle: `ALL_TAB_COLUMNS` + `ALL_COL_COMMENTS`(去重 LEFT JOIN,跟 [list_columns.oracle.sql](../web3/backend/core/sql_templates/info_schema/list_columns.oracle.sql) 同源思路)
- MySQL: `INFORMATION_SCHEMA.COLUMNS`
- 达梦: `ALL_TAB_COLUMNS`(跟 Oracle 高度一致,占位符 `?`)
- 行数 COUNT(*) 用方言的 `quote_ident()` 包识别符,避开关键字冲突
- 视图溯源:仅对 `V_` / `V$` 开头的命中视图跑 `USER_DEPENDENCIES`,附带基表行数
- 数据治理原则:只读 SELECT,不发 DML
## 相关文件
- 脚本:[scripts/find_field.py](scripts/find_field.py)
- web3 底层连接管理:[web3/backend/core/db_adapter.py](../web3/backend/core/db_adapter.py)
- web3 连接预设表 schema:[web3/backend/db/schema.sql](../web3/backend/db/schema.sql)(`connection_preset` 表)
- 一次性的 GJJ80 探测脚本(已被本 skill 取代):[web3/tests/_probe_gjj80_bankcard.py](../web3/tests/_probe_gjj80_bankcard.py)
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment