DMS 数据库通用操作 Skill
连接阿里云 DMS (MySQL) 查询与执行数据库数据,内置安全护栏。支持覆盖默认库、便捷命令、多格式导出。
核心安全原则(强制)
- 默认只读:未加
--write时仅执行SELECT / SHOW / DESCRIBE / EXPLAIN / WITH / USE,脚本自动拦截一切写操作并退出。 - 写操作必须二次确认:即使用户明确要求修改/删除数据,也必须走"预览 -> 展示影响 -> 用户确认 -> 执行"四步流程,不得跳过。
- 不做超出用户意图的修改:用户只要求"查"时绝不"改";用户要求"改 A"时绝不顺带"改 B"。
- 一次只做一件事:每条写操作独立预览、独立确认,不批量执行多条未经逐一确认的写语句。
脚本
{SKILL_DIR} = ~/.codex/skills/dms-query/scripts。主脚本 dms_exec.py。
便捷命令
# 列出所有数据库
python3 {SKILL_DIR}/dms_exec.py --databases
# 列出指定库的表(不传库名则用 DMS_DB)
python3 {SKILL_DIR}/dms_exec.py --tables # 用 DMS_DB 默认库
python3 {SKILL_DIR}/dms_exec.py --tables shop # 指定库
# 查看表结构
python3 {SKILL_DIR}/dms_exec.py --describe mydb.users
python3 {SKILL_DIR}/dms_exec.py --db shop --describe products
读取 SQL 的三种方式
# 1. 命令行直接传
python3 {SKILL_DIR}/dms_exec.py --sql "SELECT * FROM mydb.users LIMIT 5"
# 2. 从文件读取
python3 {SKILL_DIR}/dms_exec.py --file /path/to/query.sql
# 3. 从 stdin 读取
echo "SHOW DATABASES" | python3 {SKILL_DIR}/dms_exec.py
覆盖默认库
默认连接 DMS_DB 环境变量指定的库。用 --db 可临时覆盖,不影响其他终端:
python3 {SKILL_DIR}/dms_exec.py --db shop --sql "SELECT id, name FROM products LIMIT 10"
python3 {SKILL_DIR}/dms_exec.py --db mydb --tables
导出结果
# 导出 xlsx
python3 {SKILL_DIR}/dms_exec.py --sql "SELECT ..." -o result.xlsx
# 导出 csv
python3 {SKILL_DIR}/dms_exec.py --sql "SELECT ..." -o result.csv
# 导出 json(数组对象格式)
python3 {SKILL_DIR}/dms_exec.py --sql "SELECT ..." -o result.json
# TSV 原始输出(适合管道处理,不导出文件)
python3 {SKILL_DIR}/dms_exec.py --sql "SELECT ..." --raw
--display-rows N(默认 200)控制终端打印行数。导出文件时不受此限制。
查询数据(只读)
# 查看所有数据库
python3 {SKILL_DIR}/dms_exec.py --databases
# 查看某个库的表
python3 {SKILL_DIR}/dms_exec.py --tables mydb
# 查看表结构
python3 {SKILL_DIR}/dms_exec.py --describe mydb.users
# 查询数据
python3 {SKILL_DIR}/dms_exec.py --sql "SELECT id, name, email FROM mydb.users LIMIT 10"
# 查看建表语句
python3 {SKILL_DIR}/dms_exec.py --sql "SHOW CREATE TABLE mydb.users"
# 跨库查询(SQL 中用 db.table 全名即可,无需 --db)
python3 {SKILL_DIR}/dms_exec.py --sql "SELECT c.name, COUNT(*) FROM mydb.users u LEFT JOIN shop.companies c ON u.company_id = c.id GROUP BY c.name"
查询大量数据时,在 SQL 中加
LIMIT;如需全量导出,用-o file.xlsx。
运行时错误处理
脚本已内置友好错误提示,执行失败时根据输出判断原因并引导用户:
| 错误特征 | 原因 | 处理 |
|---|---|---|
Can't connect to MySQL server ... (timed out) | VPN 未连接 | 提醒用户:"DMS 为内网地址,请先连接公司 VPN 后重试" |
缺少 pymysql 模块 | 依赖未安装 | 提示执行 pip3 install pymysql -i https://pypi.tuna.tsinghua.edu.cn/simple |
缺少环境变量 DMS_* | 未配置连接参数 | 提醒用户在 ~/.zshenv 配置 DMS 环境变量后新开终端 |
拒绝执行写操作 | 未加 --write | 正常拦截,按写操作确认流程处理 |
脚本输出已包含排查建议,可直接转述给用户。无需自行猜测原因。
写操作确认流程(强制,不可跳过)
当用户明确要求修改/删除/创建数据时,必须按以下四步执行:
Step 1 - 生成预览(dry-run)
python3 {SKILL_DIR}/dms_exec.py --sql "<写操作SQL>" --write
脚本默认 dry-run:对 DML 用事务执行后 ROLLBACK 获取精确受影响行数,并 SELECT 预览受影响行;对 INSERT 展示目标表、列、值;对 DDL 给出影响说明。不实际修改数据。
Step 2 - 向用户展示影响范围
基于预览输出,用中文向用户清晰说明:
- 操作类型:INSERT / UPDATE / DELETE / DDL(具体哪种)
- 目标表:涉及的表名
- 影响行数:多少行会被修改/删除/插入
- 具体改动:
- UPDATE:哪些字段从什么值改成什么值(展示预览行)
- DELETE:将删除哪些行(展示预览行)
- INSERT:将插入什么数据(展示列和值)
- DDL:结构变更的具体内容
- 是否可逆:DROP/TRUNCATE 不可逆,需特别强调
- 无 WHERE 警告:若 UPDATE/DELETE 无 WHERE 子句,必须强调"将影响全表"
Step 3 - 等待用户明确确认
用户必须回复肯定语义("确认" / "执行" / "没问题" 等)。不得自行判断"用户应该是同意的"而跳过。 如果用户犹豫或提出修改,回到 Step 1 重新预览。
Step 4 - 执行
python3 {SKILL_DIR}/dms_exec.py --sql "<写操作SQL>" --write --confirm
执行后报告受影响行数。
流程示例
用户说:"把 users 表里 feedback_type 为 2 的记录的 feedback 字段更新为 '已处理'"
# Step 1: 预览
python3 {SKILL_DIR}/dms_exec.py \
--sql "UPDATE mydb.users SET feedback = '已处理' WHERE feedback_type = 2" \
--write
# Step 2: 展示预览结果给用户(受影响行数、预览行、不可逆性)
# Step 3: 等待用户确认
# Step 4: 确认后执行
python3 {SKILL_DIR}/dms_exec.py \
--sql "UPDATE mydb.users SET feedback = '已处理' WHERE feedback_type = 2" \
--write --confirm
参数速查
| 参数 | 说明 |
|---|---|
--sql "..." | 直接传 SQL |
--file / -f PATH | 从文件读取 SQL |
--db NAME | 覆盖默认库名(DMS_DB) |
--databases | 列出所有库 |
--tables [DB] | 列出表(可选库名) |
--describe TABLE | 查看表结构 |
-o FILE | 导出 xlsx/csv/json |
--raw | TSV 原始输出 |
--display-rows N | 终端显示行数(默认 200) |
--timeout N | 连接超时秒数(默认 15) |
--write | 允许写操作 |
--confirm | 确认执行写操作(需配合 --write) |
完成后
- 查询操作:报告行数与关键数据摘要(或导出文件路径)。
- 写操作:报告受影响行数及操作结果。