with one click
db-eda
用自然語言查詢 SQLite 或 DuckDB 資料庫。當用戶說「查資料庫」「SQL 查詢」「db eda」「自然語言查 DB」時使用。
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
Menu
用自然語言查詢 SQLite 或 DuckDB 資料庫。當用戶說「查資料庫」「SQL 查詢」「db eda」「自然語言查 DB」時使用。
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
Based on SOC occupation classification
Generate self-contained HTML architecture diagrams (inline SVG, dark theme, no JS) for blogs/READMEs. Triggers on system architecture, microservices, cloud/AWS/GCP, K8s, network topology, data flow diagrams. Use `drawio` instead when the output needs to be editable.
Generate draw.io diagrams (.drawio files) with optional PNG/SVG/PDF export. Triggers on diagram/flowchart/ER/sequence/class/network/architecture/wireframe/mockup/UI sketch requests.
使用 Gemini Nano Banana 2 產生圖片。當用戶說「產圖」「生成圖片」「generate image」「畫一張圖」時使用。
Resume/CV optimization. Analyze a resume, reposition strengths, and produce an optimized PDF tailored to a target role.
Virtual expert roundtable. Multiple thinkers analyze a document with different frameworks, then synthesize consensus/disagreements/blind spots.
Vendor proposal evaluation. Analyze technical architecture, pricing, and market benchmarks from a proposal PDF/Doc. Output evaluation report + comparison.
| name | db-eda |
| description | 用自然語言查詢 SQLite 或 DuckDB 資料庫。當用戶說「查資料庫」「SQL 查詢」「db eda」「自然語言查 DB」時使用。 |
| argument-hint | [db 檔案路徑 + 問題,如 'data.db 最近一週的銷售額'] |
| allowed-tools | Bash(python3*), Bash(pip3*), Read, Write |
| author | Maki |
| version | 1.0.0 |
| tags | ["database","sqlite","duckdb","eda","data"] |
| required_env | [] |
讓用戶用自然語言對 SQLite 或 DuckDB 資料庫提問,自動轉成 SQL 執行並格式化輸出。全程 read-only,安全第一。
python3 -c "
import sqlite3; print('sqlite3: OK')
try:
import duckdb; print(f'duckdb: {duckdb.__version__}')
except ImportError:
print('duckdb: NOT_FOUND (only needed for .duckdb files)')
"
.duckdb 檔案時需要(pip3 install duckdb)根據 $ARGUMENTS 判斷:
.db / .sqlite → SQLite,.duckdb → DuckDBpython3 << 'PYEOF'
import sqlite3, json, sys
DB_PATH = "USER_DB_PATH"
# 強制 read-only 連線
conn = sqlite3.connect(f"file:{DB_PATH}?mode=ro", uri=True)
# 取得所有 table 的 DDL
cursor = conn.execute("""
SELECT name, sql FROM sqlite_master
WHERE type='table' AND sql IS NOT NULL
ORDER BY name
""")
tables = cursor.fetchall()
for name, ddl in tables:
print(f"\n-- Table: {name}")
print(ddl)
# Sample data (前 3 行)
sample = conn.execute(f'SELECT * FROM "{name}" LIMIT 3').fetchall()
cols = [d[0] for d in conn.execute(f'SELECT * FROM "{name}" LIMIT 0').description]
print(f"-- Columns: {cols}")
print(f"-- Sample ({len(sample)} rows): {sample[:2]}")
conn.close()
PYEOF
python3 << 'PYEOF'
import sys
try:
import duckdb
except ImportError:
print("ERROR: pip3 install duckdb")
sys.exit(1)
DB_PATH = "USER_DB_PATH"
conn = duckdb.connect(DB_PATH, read_only=True)
tables = conn.execute("SHOW TABLES").fetchall()
for (name,) in tables:
print(f"\n-- Table: {name}")
ddl = conn.execute(f'DESCRIBE "{name}"').fetchall()
for col_name, col_type, *_ in ddl:
print(f"-- {col_name}: {col_type}")
sample = conn.execute(f'SELECT * FROM "{name}" LIMIT 3').fetchall()
print(f"-- Sample: {sample[:2]}")
conn.close()
PYEOF
將 schema + sample data 展示給用戶確認目標 table。
基於 schema context,Claude 將用戶的自然語言問題轉為 SQL。
轉換規則:
LIMIT 100(除非用戶明確要全部)"column" 包裹避免保留字衝突(SQLite 和 DuckDB 通用)展示 SQL 給用戶確認後才執行。
python3 << 'PYEOF'
import sqlite3, sys, re
DB_PATH = "USER_DB_PATH"
DB_TYPE = "sqlite" # or "duckdb"
SQL = """USER_SQL_HERE"""
# === 安全檢查 ===
# 1. 禁止多 statement(分號只能出現在結尾)
sql_stripped = SQL.strip().rstrip(';')
if ';' in sql_stripped:
print("BLOCKED: Multiple statements not allowed.", file=sys.stderr)
sys.exit(1)
# 2. 首 token 必須是 SELECT 或 WITH
first_token = sql_stripped.split()[0].upper() if sql_stripped.split() else ""
if first_token not in ("SELECT", "WITH"):
print(f"BLOCKED: Only SELECT/WITH queries allowed (got: {first_token}).", file=sys.stderr)
sys.exit(1)
# 3. 阻擋危險關鍵字(即使在子查詢中)
dangerous = re.compile(
r'(?i)\b(DROP|DELETE|UPDATE|INSERT|ALTER|ATTACH|DETACH|CREATE|VACUUM|ANALYZE|REINDEX|PRAGMA)\b'
)
if dangerous.search(SQL):
print("BLOCKED: Dangerous keyword detected.", file=sys.stderr)
sys.exit(1)
# 4. 強制 LIMIT
if not re.search(r'(?i)\bLIMIT\b', SQL):
SQL = f"{sql_stripped} LIMIT 100;"
# === 執行 ===
conn = None
try:
if DB_TYPE == "sqlite":
conn = sqlite3.connect(f"file:{DB_PATH}?mode=ro", uri=True)
# 額外防護:用 authorizer 阻擋非 SELECT 操作
def authorizer(action, arg1, arg2, db_name, trigger):
ALLOWED = {sqlite3.SQLITE_SELECT, sqlite3.SQLITE_READ,
sqlite3.SQLITE_FUNCTION, sqlite3.SQLITE_RECURSIVE}
return sqlite3.SQLITE_OK if action in ALLOWED else sqlite3.SQLITE_DENY
conn.set_authorizer(authorizer)
else:
import duckdb
conn = duckdb.connect(DB_PATH, read_only=True)
cursor = conn.execute(SQL)
columns = [d[0] for d in cursor.description]
rows = cursor.fetchall()
# Markdown table 輸出
print(f"| {' | '.join(columns)} |")
print(f"| {' | '.join(['---'] * len(columns))} |")
for row in rows:
print(f"| {' | '.join(str(v) if v is not None else '' for v in row)} |")
print(f"\n({len(rows)} rows returned)")
except Exception as e:
print(f"ERROR: {e}", file=sys.stderr)
sys.exit(1)
finally:
if conn is not None:
conn.close()
PYEOF
csv-to-chart 畫圖表| 防線 | 說明 |
|---|---|
| Read-only 連線 | SQLite ?mode=ro、DuckDB read_only=True |
| 首 token 檢查 | 只允許 SELECT / WITH 開頭 |
| 多 statement 阻擋 | 禁止分號分隔的多語句 |
| 危險關鍵字過濾 | DROP/DELETE/UPDATE/INSERT/ALTER/CREATE/ATTACH/PRAGMA 等 |
| SQLite authorizer | set_authorizer() 在 opcode 層阻擋非 SELECT 操作 |
| 強制 LIMIT | 沒有 LIMIT 的查詢自動加 LIMIT 100 |
| 用戶確認 | SQL 執行前展示給用戶確認 |
如果檔案是 .duckdb:
import duckdb
conn = duckdb.connect("USER_DB_PATH", read_only=True)
# Schema: SHOW TABLES; DESCRIBE table_name;
# 其餘流程相同
需要 pip3 install duckdb。