数据库
需要在本地用 DuckDB 查询附加数据库或临时文件时…
在已安装 DuckDB 的情况下,将用户问题转为 DuckDB SQL,针对 session 状态数据库或 ad-hoc 文件执行,并处理模式判定、schema、大小估算、错误与结果展示。
🧪 尚未被验证(还没有小呱复用过的记录,不代表不好)
GDI C 38/100
进化评分(GDI)
综合排序依据 —— 四个维度的加权结果,让你看出「为什么这条排在前面」
内在质量 55/100 ×0.35
使用度 0/100 ×0.30
口碑 50/100 ×0.20
新鲜度 60/100 ×0.15
适用场景
需要在本地用 DuckDB 查询附加数据特定
解决思路
- 接收输入 `$@`,并按顺序执行技能步骤。
- Step 1:查找已有状态文件:先设置 `STATE_DIR=""`;`test -f .duckdb-skills/state.sql && STATE_DIR=".duckdb-skills"`;计算 `PROJECT_ROOT="$(git rev-parse --show-toplevel 2>/dev/null || echo "$PWD")"` 和 `PROJECT_ID="$(echo "$PROJECT_ROOT" | tr '/' '-')"`;再 `test -f "$HOME/.duckdb-skills/$PROJECT_ID/state.sql" && STATE_DIR="$HOME/.duckdb-skills/$PROJECT_ID"`。
- Step 1:若找到状态文件,运行 `duckdb -init "$STATE_DIR/state.sql" -c "SHOW DATABASES;"` 验证其引用的数据库仍可访问。
- Step 1:判断模式:若存在 `--file` 标志、SQL 引用文件路径/字面量(如 `FROM 'data.csv'`)或 `STATE_DIR` 为空,则为 ad-hoc mode;若 `STATE_DIR` 已设置且输入引用表名、是自然语言、或不含文件引用的 SQL,则为 session mode。
- Step 1:若没有状态文件且未引用文件,则回退到针对 `:memory:` 的 ad-hoc mode,用户必须在 SQL 中直接引用文件。
- Step 1:若状态文件存在但其中任一 `ATTACH` 失败,警告用户并回退到 ad-hoc mode。
- Step 2:运行 `command -v duckdb` 检查 DuckDB 是否安装;若未找到,委托 `/duckdb-skills:install-duckdb`,然后继续。
- Step 3:若输入是自然语言(不是有效 SQL),使用 Friendly SQL 参考生成 SQL。
- Step 3:在 session mode 中,先运行 `duckdb -init "$STATE_DIR/state.sql" -csv -c "SELECT table_name FROM duckdb_tables() ORDER BY table_name;"` 获取 schema 以辅助查询生成。
- Step 3:对相关表运行 `duckdb -init "$STATE_DIR/state.sql" -csv -c "DESCRIBE <table_name>;"`。
- Step 3:使用 schema 上下文和 Friendly SQL 参考生成最合适的查询。
- Step 4:执行前估算查询是否可能产生非常大、消耗大量 token 的结果。
- Step 4:session mode 中检查涉及表的行数:`duckdb -init "$STATE_DIR/state.sql" -csv -c "SELECT table_name, estimated_size, column_count FROM duckdb_tables() WHERE table_name IN ('<table1>', '<table2>');"`。
- Step 4:ad-hoc mode 中探测源:`duckdb :memory: -csv -c "SET allowed_paths=['FILE_PATH']; SET enable_external_access=false; SET allow_persistent_secrets=false; SET lock_configuration=true; SELECT count() AS row_count FROM 'FILE_PATH';"`。
- Step 4:评估:若查询已有 `LIMIT`、`count()` 或其他限制输出的聚合,则安全并继续。
- Step 4:若源有 >1M 行且查询没有 `LIMIT` 或聚合,则告诉用户:此查询会返回非常大的结果集,在这里显示会消耗大量 token 并增加成本,建议添加 `LIMIT 1000` 或聚合以保持输出可管理;并在按原样运行前请求确认。
- Step 4:若数据大小 >10 GB,额外警告用户该表超过 10 GB,查询可能耗时较久;用户确认后继续。
- Step 4:对内在有界的查询跳过此步,例如 `DESCRIBE`、`SUMMARIZE`、聚合、`count()`。
- Step 5:ad-hoc mode 执行沙箱查询:`duckdb :memory: -csv <<'SQL'`,并在 heredoc 内设置 `SET allowed_paths=['FILE_PATH']; SET enable_external_access=false; SET allow_persistent_secrets=false; SET lock_configuration=true;`,然后执行 `<QUERY>;`。
- Step 5:ad-hoc mode 中将 `FILE_PATH` 替换为从查询或 `--file` 参数提取的实际文件路径;若引用多个文件,将所有路径加入 `allowed_paths` 列表。
- Step 5:session mode 执行用户信任数据库查询:`duckdb -init "$STATE_DIR/state.sql" -csv -c "<QUERY>"`。
- Step 5:多行查询使用 heredoc 和 `-init`:`duckdb -init "$STATE_DIR/state.sql" -csv <<'SQL'`,然后执行 `<QUERY>;`。
- Step 5:多行查询始终使用 heredoc(`<<'SQL'`),避免 shell 引号问题。
- Step 6:语法错误时显示错误,建议修正后的查询并重新运行。
- Step 6:缺少扩展时(如 `Extension "X" not loaded`),委托 `/duckdb-skills:install-duckdb <ext>`,然后重试。
- Step 6:表不存在时(session mode),用 `FROM duckdb_tables()` 列出可用表并建议修正。
- Step 6:文件不存在时(ad-hoc mode),使用 `find "$PWD" -name "<filename>" 2>/dev/null` 定位文件并建议修正路径。
- Step 6:遇到持久或不清晰的 DuckDB 错误时,使用 `/duckdb-skills:duckdb-docs <error message or relevant keywords>` 搜索文档,然后应用修复并重试。
- Step 7:向用户展示查询输出。
- Step 7:若结果超过 100 行,说明截断并建议在查询中添加 `LIMIT`。
- Step 7:对自然语言问题,额外提供结果的简要解读。
- 生成 SQL 时优先使用 DuckDB Friendly SQL 紧凑子句:`FROM`-first,例如 `FROM table WHERE x > 10`(隐式 `SELECT *`)。
- 生成 SQL 时优先使用 `GROUP BY ALL`,自动按所有非聚合列分组。
- 生成 SQL 时优先使用 `ORDER BY ALL`,按所有列排序以获得确定性结果。
- 生成 SQL 时优先使用 `SELECT * EXCLUDE (col1, col2)`,从通配符中删除列。
- 生成 SQL 时优先使用 `SELECT * REPLACE (expr AS col)`,原地转换列。
- 生成 SQL 时优先使用 `UNION ALL BY NAME`,合并列顺序不同的表。
- 生成 SQL 时优先使用百分比 `LIMIT`:`LIMIT 10%` 返回一定比例的行。
- 生成 SQL 时优先使用前缀别名:`SELECT x: 42` 代替 `SELECT 42 AS x`。
- 生成 SQL 时允许在 SELECT 列表中使用尾随逗号。
- 生成 SQL 时优先使用 `count()`,无需 `count(*)`。
- 生成 SQL 时优先使用可复用别名:在 `WHERE`/`GROUP BY`/`HAVING` 中使用列别名。
- 生成 SQL 时优先使用横向列别名:`SELECT i+1 AS j, j+2 AS k`。
- 生成 SQL 时优先使用 `COLUMNS(*)` 跨列应用表达式,并支持 regex、`EXCLUDE`、`REPLACE`、lambdas。
- 生成 SQL 时优先使用 `FILTER` 子句:`count() FILTER (WHERE x > 10)` 进行条件聚合。
- 生成 SQL 时优先使用 `GROUPING SETS` / `CUBE` / `ROLLUP` 进行高级多层聚合。
- 生成 SQL 时优先使用 Top-N per group:`max(col, 3)` 返回前 3 个为列表;也可用 `arg_max(arg, val, n)`、`min_by(arg, val, n)`。
- 生成 SQL 时优先使用 `DESCRIBE table_name` 获取 schema 摘要(列名和类型)。
- 生成 SQL 时优先使用 `SUMMARIZE table_name` 获取即时统计画像。
- 生成 SQL 时优先使用 `PIVOT` / `UNPIVOT` 在宽格式和长格式间重塑。
- 生成 SQL 时优先使用 `SET VARIABLE x = expr` 定义 SQL 级变量,并用 `getvariable('x')` 引用。
- 生成 SQL 时优先使用直接文件查询:`FROM 'file.csv'`、`FROM 'data.parquet'`。
- 生成 SQL 时优先使用 Globbing:`FROM 'data/part-*.parquet'` 读取多个文件。
- 生成 SQL 时依赖自动检测:CSV 表头和 schema 会自动推断。
- 生成 SQL 时优先使用点操作符链式调用:`'hello'.upper()` 或 `col.trim().lower()`。
- 生成 SQL 时优先使用列表推导:`[x*2 FOR x IN list_col]`。
- 生成 SQL 时优先使用列表/字符串切片:`col[1:3]`,负数索引 `col[-1]`。
- 生成 SQL 时优先使用 `STRUCT.*` 记法:`SELECT s.* FROM (SELECT {'a': 1, 'b': 2} AS s)`。
- 生成 SQL 时优先使用方括号列表:`[1, 2, 3]`。
- 生成 SQL 时优先使用 `format()`:`format('{}->{}', a, b)` 进行字符串格式化。
- 生成 SQL 时优先使用 ASOF joins 对有序数据(如时间戳)做近似匹配。
- 生成 SQL 时优先使用 POSITIONAL joins 按位置而非键匹配行。
- 生成 SQL 时优先使用 LATERAL joins 在子查询中引用前面的表表达式。
- 数据修改时优先使用 `CREATE OR REPLACE TABLE`,无需先 `DROP TABLE IF EXISTS`。
- 数据修改时优先使用 `CREATE TABLE ... AS SELECT (CTAS)` 从查询结果创建表。
- 数据修改时优先使用 `INSERT INTO ... BY NAME` 按列名而非位置匹配列。
- 数据修改时优先使用 `INSERT OR IGNORE INTO` / `INSERT OR REPLACE INTO` 实现 upsert 模式。
适用边界 · 注意事项
- 未安装 DuckDB 且无法执行 `/duckdb-skills:install-duckdb` 或无法加载所需扩展时。
- 需要访问 ad-hoc 沙箱 `allowed_paths` 之外的本地文件、外部网络或持久密钥,而设置禁止这些访问时。
- 用户不接受对超大结果添加 `LIMIT`/聚合,或数据超过 10 GB 且不允许等待时。