关于 redshift
redshift 是面向 AI 编码 Agent 的只读 Redshift 探索与业务分析技能,通过 AWS Data API 访问预置集群和 Redshift Serverless,并支持多个命名连接。
主要功能
- 01执行只读 SQL 查询
- 02浏览架构、表和列
- 03查看 DDL 与表元数据
- 04搜索对象并抽样数据
- 05分析数据概况和磁盘用量
- 06将查询结果保存为 CSV
适用场景
- 01探索陌生的 Redshift 架构
- 02用 SQL 调查业务指标
- 03检查表大小和存储用量
- 04在本地分析已保存的查询结果
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ onsen-ai/ redshift-skill --skill redshift安装后在 Claude Code 中输入/redshift确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
.DS_Store.gitignoreLICENSEREADME.mdscripts/.DS_Storecolumns.pyddl.pyanalyze.pyprofile.pyschemas.pyspace.pyquery.pysearch.pysample.pysetup.pytable_info.pytables.pyscripts/lib/__init__.pyclient.pyformatter.pyscripts/sql/extended_table_info.sqlgenerate_external_tbl_ddl.sqlgenerate_database_ddl.sqlgenerate_schema_ddl.sqlgenerate_udf_ddl.sqlgenerate_group_ddl.sqlgenerate_tbl_ddl.sqlspace_used_per_tbl.sqlgenerate_view_ddl.sqltests/test_config.py详细介绍
Redshift 技能
通过 AWS Data API 以只读方式探索 Redshift 并进行业务分析。支持预置集群和 Redshift Serverless。跨平台(Mac + Windows)。适用于任何 AI 编码 Agent。
所有脚本都位于 ${CLAUDE_SKILL_DIR}/scripts/,只需要 Python 3 + AWS CLI。
Python 命令
读取 ~/.redshift-skill/config.json,并使用 "python" 键指定的 Python 命令。
如果配置文件尚不存在,请先尝试 python3 --version,失败时再尝试 python --version。
本文档中的 PYTHON 均指检测到的 Python 命令。
首次设置
你无法直接运行设置向导——它需要在交互式终端中输入。
检查 ~/.redshift-skill/config.json 是否存在:
- **如果存在:**读取该文件以确认连接详情。
- **如果不存在:**告诉用户在终端中运行设置向导:
在终端中运行以下命令以配置 Redshift 连接:
python3 scripts/setup.py(在 Windows 上,请使用
python代替python3)
在用户确认设置完成之前,不要运行任何查询。
连接选择
此技能支持多个命名连接(例如,每个 AWS 账户对应一个连接)。配置结构:
{
"default": "prod",
"connections": {
"prod": { "profile": "...", "region": "eu-west-1", "workgroup": "...", "database": "dev" },
"other": { "profile": "...", "region": "eu-west-1", "cluster": "...", "db_user": "...", "database": "main" }
},
"python": "/usr/bin/python3"
}
- 每个脚本都接受
--connection NAME;如果未指定,则使用default连接。 - 列出连接:
PYTHON /Users/dobo/.claude/skills/redshift/scripts/setup.py --list - 切换默认连接:
PYTHON /Users/dobo/.claude/skills/redshift/scripts/setup.py --set-default NAME - 移除连接:
PYTHON /Users/dobo/.claude/skills/redshift/scripts/setup.py --remove NAME - 添加连接:重新运行
setup.py(交互式——请用户运行);程序会询问名称,并保留其他连接。 - 命名连接功能推出前的配置(字段位于顶层)会被读取为一个名为
main的连接。
当用户提到账户、集群或项目时,将其映射到匹配的连接,并在每次调用时传入
--connection NAME。否则使用默认连接,并说明使用的是哪个连接。
快速参考
| 任务 | 脚本 | 使用场景 | 关键参数 |
|---|---|---|---|
| 运行 SQL | query.py | 执行任意只读查询 | "SELECT ..." 或 --sql-file=PATH |
| 列出架构 | schemas.py | 入门起点——查看有哪些架构 | |
| 列出表 | tables.py | 浏览表,并在查询前检查行数和大小 | --schema=NAME |
| 列出列 | columns.py | 了解列类型、编码、分布键/排序键 | --schema=NAME --table=NAME |
| 表 DDL | ddl.py | 获取完整的 CREATE TABLE 定义,包括编码、分布键和排序键 | --schema=NAME --name=NAME |
| 视图 DDL | ddl.py | 获取 CREATE VIEW 定义 | --type=view --schema=NAME --name=NAME |
| 架构 DDL | ddl.py | 获取带授权信息的 CREATE SCHEMA 语句 | --type=schema [--name=NAME] |
| 数据库 DDL | ddl.py | 获取 CREATE DATABASE 语句 | --type=database |
| UDF DDL | ddl.py | 获取函数定义(SQL + Python) | --type=udf [--schema=NAME] |
| 外部 DDL | ddl.py | 获取 Spectrum 外部表 DDL | --type=external [--schema=NAME] |
| 用户组 DDL | ddl.py | 获取用户组定义 | --type=group |
| 表元数据 | table_info.py | 在编写大型查询前检查大小、行数、数据倾斜和编码 | --schema=NAME --table=NAME |
| 搜索对象 | search.py | 不知道确切名称时查找表或列 | --pattern=TEXT |
| 采样数据 | sample.py | 快速查看实际值——编写查询前务必执行此操作 | --schema=NAME --table=NAME |
| 磁盘用量 | space.py | 找出最大的表并识别存储问题 | [--schema=NAME] [--top=N] |
| 数据概况 | profile.py | 按列统计数据(空值、基数、最小值/最大值/平均值) | --schema=NAME --table=NAME |
| 本地分析 | analyze.py | 在本地分析保存的结果,无需访问 Redshift | FILE --describe |
通用选项(适用于所有 Redshift 脚本)
| 选项 | 说明 |
|---|---|
--format=txt|csv|json | 终端显示格式(默认:txt) |
--save-format=txt|csv|json | 文件保存格式(默认:csv) |
--save=PATH | 保存到指定文件路径 |
--no-save | 不自动保存到 ~/redshift-exports/ |
--save-sql | 将 SQL 查询与结果一同保存为 .sql 文件 |
--sql-file=PATH | 从文件读取 SQL(仅限 query.py) |
--connection=NAME | 从 ~/.redshift-skill/config.json 中选择已命名的连接(默认使用已保存的 default) |
--profile=NAME | 覆盖 AWS 配置文件 |
--cluster=NAME | 覆盖集群(预置集群) |
--workgroup=NAME | 覆盖工作组(无服务器) |
--database=NAME | 覆盖数据库 |
--db-user=NAME | 覆盖数据库用户(仅限预置集群) |
--timeout=N | 最长等待秒数(默认:120) |
--max-rows=N | 最多获取行数(默认:1000) |
输出与文件保存
所有查询结果都会自动保存到 ~/redshift-exports/query-{timestamp}.csv。
终端会显示对齐的 txt 格式预览(前 200 行)。保存文件默认采用 CSV 格式,以便与电子表格兼容。
这意味着你始终可以获得:
- 内联预览(txt 格式的 200 行)——足以了解数据结构并回答快速问题
- 磁盘上的完整 CSV 文件——用于通过
analyze.py进行深入分析,或供用户在电子表格中打开
--format 控制终端显示格式(默认:txt)。--save-format 控制保存文件格式(默认:csv)。使用 --save-sql 还可将 SQL 查询另存为对应的 .sql 文件。使用 --no-save 可跳过自动保存。使用 --save=PATH 可保存到指定位置。
防护措施
这些规则可保护集群免受高开销查询的影响。请遵循这些规则,但也要灵活判断。如果用户明确要求执行可能违反规则的操作,请说明其中的权衡;在用户确认后继续操作。
- 绝不对超过 10K 行的表使用
SELECT *——此工具用于探索和分析,而非导出数据。请改用聚合、筛选或sample.py。对于较小的表,使用SELECT *没问题。 - 探索不熟悉的表时,始终添加
LIMIT(默认 LIMIT 为 100)。 - 先检查行数——编写查询前,先运行
tables.py --schema=X,了解数据情况。 - 大型表优先使用聚合——使用带
GROUP BY的COUNT、SUM、AVG,而不是提取原始行。对于小型表,以及探索或了解数据时,直接使用原始数据完全没问题。 - 超大型事实表应按排序键筛选——尤其是在按特定时间段筛选按日期/时间戳排序的表时。Redshift 会使用区域映射跳过数据块,因此日期范围筛选效率很高。并非严格要求,但对于超过 100M 行的表,强烈建议这样做。
- 可以使用联接——只要联接条件正确,并且对结果进行适当聚合或筛选,Redshift 就能很好地处理大型表联接。风险不在联接本身,而在于从联接结果中返回不受限制的原始数据。
- 避免意外的交叉联接——除非确实需要笛卡尔积(例如按设计展开数据),否则始终添加
ON/USING。 - 探索时,优先使用
LIMIT+ORDER BY,而非不受限制的查询。
规模参考:
| 表大小 | 方法 |
|---|---|
| <10K 行 | 可自由探索,使用 SELECT * 没问题 |
| 10K–1M 行 | 添加 WHERE 或 LIMIT;查询整张表时优先使用聚合 |
| >1M 行 | 始终进行聚合或筛选,绝不使用 SELECT *;大型事实表应使用排序键筛选 |
SQL 规范
你编写的每条 SQL 查询都必须遵循以下规则:
始终为 SQL 添加注释
说明业务意图,而不只是操作方式。对于复杂查询,请使用分节标题。
始终向用户展示 SQL
- 短查询(<10 行): 在内联内容中展示完整 SQL,并添加注释
- 长查询(>10 行): 保存到
~/redshift-exports/query-{timestamp}.sql,在内联内容中展示关键部分,并引用保存的文件
对复杂查询使用 --sql-file
对于较长的 SQL,先将其写入文件,再使用 --sql-file 执行:
PYTHON ${CLAUDE_SKILL_DIR}/scripts/query.py --sql-file=~/redshift-exports/my_query.sql
提示 — 无需在 LLM 上下文中读写,即可内联多行 SQL: 如果需要在一次 Bash 调用中写入 SQL 文件并运行查询:
Mac/Linux — heredoc:
cat > "/path/to/query.sql" << 'EOSQL'
-- Your SQL here
SELECT ...
EOSQL
PYTHON ${CLAUDE_SKILL_DIR}/scripts/query.py --sql-file="/path/to/query.sql" --save="/path/to/results.csv" --save-sql
'EOSQL' 引号可防止 Shell 变量在 SQL 中展开。
跨平台 — Python:
PYTHON -c "
sql = '''
-- Your SQL here
SELECT ...
'''
open('/path/to/query.sql', 'w').write(sql.strip())
"
PYTHON ${CLAUDE_SKILL_DIR}/scripts/query.py --sql-file="/path/to/query.sql" --save="/path/to/results.csv" --save-sql
提示 — 通过替换值重复使用 SQL 文件: 如果已有 SQL 文件,只需更改特定值(例如将滚动日期向后推一周),可以使用单行命令替换,而不必在 LLM 上下文中重写整个文件:
Mac/Linux — sed:
sed "s/2026-03-15/2026-03-22/g; s/2026-03-21/2026-03-28/g" original_query.sql > query.sql
跨平台 — Python:
PYTHON -c "open('query.sql','w').write(open('original_query.sql').read().replace('2026-03-15','2026-03-22').replace('2026-03-21','2026-03-28'))"
然后执行:
PYTHON ${CLAUDE_SKILL_DIR}/scripts/query.py --sql-file=query.sql --save="/path/to/results.csv" --save-sql
对于需要进行多处替换的模板,可以使用 {{WC_START}} 之类的命名占位符,而不是具体日期。
格式规范
------------------------------------------------------------------------------------------------------------------------
-- Monthly revenue by region
-- Purpose: Aggregate order line items by region for the last 12 months
-- Filters: Excludes cancelled orders and zero-quantity items
------------------------------------------------------------------------------------------------------------------------
WITH monthly_revenue AS (
SELECT r.region_name, -- region dimension
DATE_TRUNC('month', o.order_date) :: DATE AS month_nk,
SUM(o.quantity) AS total_quantity,
SUM(o.line_total) AS total_revenue,
SUM(o.margin) AS total_margin,
COUNT(DISTINCT o.customer_id) AS unique_customers
FROM sales.fact_order_lines o
JOIN sales.dim_regions r USING (region_id)
WHERE o.order_date >= DATEADD(month, -12, CURRENT_DATE)
AND o.quantity > 0
AND o.order_status <> 'cancelled'
GROUP BY 1, 2
)
SELECT region_name,
month_nk,
total_quantity,
total_revenue,
total_margin,
unique_customers,
-- margin percentage
ROUND(total_margin / NULLIF(total_revenue, 0) * 100, 2) AS margin_pct
FROM monthly_revenue
ORDER BY region_name, month_nk
主要格式规则:
- 在查询上方使用
--短划线作为分节标题 SELECT、FROM、JOIN、WHERE、GROUP BY、ORDER BY左对齐- 每行一个列——绝不将多个列写在同一行。每个列表达式都应独占一行,并包含其
AS别名。 - 列别名中的
AS应对齐到统一的列位置 - 对不明显的业务逻辑添加行内注释
- CTE 名称应描述业务概念,而不是技术操作
充分添加注释
每个查询都必须包含解释原因的注释,而不只是说明内容。应将 SQL 视作文档,以便下一位阅读它的人(或下一个 Agent)理解。
- 每个查询顶部的标题块:用途、数据源、关键假设、参数
- 逻辑块之间的分节符(由短划线
--组成的行),例如实际值、预算、透视 CTE 之间 - 为不明显的表达式添加行内注释,例如客户估算公式、业务规则、筛选条件的原因
- 添加 CTE 级注释,说明每个 CTE 生成的内容,以及将其作为独立步骤的原因
------------------------------------------------------------------------------------------------------------------------
-- Weekly Sales Scorecard
-- Purpose: Core trading metrics with TY/LP/LY comparisons and BU/LV variances
-- Source: fact_basket_items (actuals), fact_commercial_budget_all (BU)
-- Params: Change the date in the periods CTE to set the reporting period
-- Notes:
-- - Customer estimation done per channel first, then summed to total
-- - BU/LV only have sales and margin — derivative ratios are actuals-only
------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------
-- ACTUALS: per channel for correct customer estimation
------------------------------------------------------------------------------------------------------------------------
利用 Redshift 别名重用
Redshift 允许在同一个 SELECT 中引用后续使用的列别名。利用这一点,避免为派生列创建不必要的中间 CTE。
应这样做——在单个 SELECT 中重用别名:
SELECT SUM(quantity) AS volume,
COUNT(DISTINCT basket_sk) AS orders,
1.0 * volume / NULLIF(orders, 0) AS ipb
FROM fact_basket_items
不要这样做——仅为计算派生列而额外创建 CTE:
-- BAD: extra CTE only needed because standard SQL can't reuse aliases
base AS (
SELECT SUM(quantity) AS volume, COUNT(DISTINCT basket_sk) AS orders
FROM fact_basket_items
)
SELECT volume, orders, 1.0 * volume / NULLIF(orders, 0) AS ipb
FROM base
这适用于所有派生列:比率、差异、客户估算、利润率等。如果某个 CTE 的唯一作用是引用上一步中的别名,就应将其合并到来源 SELECT 中。
使用 GROUP BY ALL 或位置式 GROUP BY
Redshift 支持 GROUP BY ALL(按 SELECT 中所有非聚合列分组)和位置式 GROUP BY 1, 2, 3。优先使用这些方式,而不是在 GROUP BY 子句中重复冗长的 CASE 表达式。
应这样做:
SELECT dp.period_name,
f.country_sk,
CASE WHEN ps.composite_rnk <= 100 THEN 'Top 100 SKUs'
ELSE 'Other SKUs' END AS sku_segment,
SUM(f.revenue_excl_vat_all_gbp) AS sales
FROM ...
GROUP BY ALL
不要这样做——在 GROUP BY 中重复 CASE 表达式:
GROUP BY dp.period_name, f.country_sk,
CASE WHEN ps.composite_rnk <= 100 THEN 'Top 100 SKUs' ELSE 'Other SKUs' END
当所有非聚合列都应参与分组时,使用 GROUP BY ALL。当需要对特定位置使用 ROLLUP 或 GROUPING SETS 时,使用 GROUP BY 1, 2, 3。使用 ROLLUP 时,位置引用最清晰:GROUP BY ROLLUP(1, 2), 3。
架构探索工作流
探索陌生架构时,采用循序渐进的方法。不必严格遵循此顺序——如果用户的意图明确具体,可以直接跳到相关步骤。尽可能并行执行各步骤。
- 了解整体情况 —
schemas.py→ 查看有哪些架构 - 浏览表 —
tables.py --schema=X→ 查看行数和大小 - 了解结构 —
columns.py --schema=X --table=Y→ 查看列类型和键 - 检查元数据 —
table_info.py→ 查看分布、排序键和未排序百分比 - 先抽样 —
sample.py --limit=5→ 查看实际数据值 - 按需分析 —
profile.py→ 查看每列的空值、基数、最小值和最大值 - 编写有针对性的查询 — 现在你已掌握足够信息,可以编写安全、高效的 SQL
- 在本地分析 — 使用
analyze.py分析保存的结果,以便后续跟进
快捷方式: 如果用户问“上个月有多少订单?”,不必运行 6 个探索脚本。查看表大小、编写查询并运行即可。
业务分析工作流
以下是处理常见业务问题的思路。像产品分析师、商业分析师或 BI 开发人员一样思考。
了解业务表现
- 从核心指标入手 — 该时段的总收入、订单数、客户数
- 按维度细分 — 时间(日/周/月)、地区、渠道、产品类别
- 比较不同时段 — 本月与上月、本年与去年、与去年同期比较
- 找出异常值 — 哪些细分群体明显高于或低于预期?
根因分析
当出现异常时(“上周收入下降了 15%”):
- 确认异常 — 异常是否真实?检查数据源,并与其他指标比较
- 拆解指标 — 是数量(订单减少)还是金额(平均订单金额下降)导致的?
- 按维度切分 — 哪个地区/渠道/类别导致了变化?
- 深入分析异常细分 — 该细分发生了什么变化?新产品?定价?库存问题?
- 关联事件 — 促销开始/结束、价格变化、缺货、季节性因素
常见分析模式
| 模式 | 方法 | SQL 结构 |
|---|---|---|
| 趋势分析 | 跟踪指标随时间的变化 | GROUP BY date/month + SUM/COUNT,比较同比/环比 |
| 同期群分析 | 按首次购买分组,跟踪留存 | 按客户计算 MIN(order_date),然后回连 |
| 分布分析 | 了解数值的分布情况 | NTILE(100)、百分位数,在本地使用 analyze.py --hist |
| 前/后 N 名 | 表现最佳和最差的对象 | ORDER BY metric DESC LIMIT N |
| 同比比较 | 年度增长比较 | 按日期偏移 1 年进行自连接,或使用 LAG() 窗口函数 |
| 漏斗分析 | 各步骤的转化情况 | 按步骤计算 COUNT(DISTINCT user_id),计算流失率 |
| 贡献度/帕累托分析 | 哪些项目贡献了 80% 的收入 | 累计 SUM() OVER (ORDER BY ...),找出达到 80% 的临界点 |
| 细分 | 按行为对实体分组 | 使用 CASE WHEN 或 NTILE 分桶,然后分析每个细分群体 |
脚本详情
query.py — 执行 SQL
运行任意只读 SQL 查询。可以将 SQL 作为命令行参数传入,也可以从文件读取。
PYTHON ${CLAUDE_SKILL_DIR}/scripts/query.py "SELECT count(1) FROM sales.fact_orders"
PYTHON ${CLAUDE_SKILL_DIR}/scripts/query.py --sql-file=~/redshift-exports/my_query.sql
count
-----
12500000
1 rows returned (1 total). Duration: 25ms
Results saved to: ~/redshift-exports/query-20260318_150505.csv
schemas.py — 列出架构
列出所有用户架构及其所有者。探索的起点。
PYTHON ${CLAUDE_SKILL_DIR}/scripts/schemas.py
schema_name owner
----------- ---------
public admin
sales etl_user
marketing etl_user
...
tables.py — 列出表
列出架构中的表,并显示行数、大小、分布样式和排序键。编写查询前先运行此脚本,了解表的情况。
PYTHON ${CLAUDE_SKILL_DIR}/scripts/tables.py --schema=sales
table_name row_count size_mb diststyle sortkey1 unsorted pct_used
-------------- ---------- ------- --------- ---------- -------- --------
dim_customers 250000 120 ALL customer_id 0.00 0.0100
dim_products 15000 48 ALL product_id 0.00 0.0000
fact_orders 85000000 45000 KEY(...) order_date 12.50 5.8600
...
columns.py — 列出列
显示列名、数据类型、编码、分布键和排序键位置。适用于表、视图和延迟绑定视图。
PYTHON ${CLAUDE_SKILL_DIR}/scripts/columns.py --schema=sales --table=fact_orders
pos column_name data_type max_len encoding distkey sortkey
--- ------------- ----------------- ------- -------- ------- -------
1 order_id CHARACTER VARYING 200 lzo False 0
2 order_date DATE az64 False 1
3 customer_id CHARACTER VARYING 200 lzo True 0
...
ddl.py — 生成 DDL
为 7 种对象类型生成 DDL。完整的 CREATE TABLE 定义包含编码、分布键、排序键、约束、注释和所有权。
PYTHON ${CLAUDE_SKILL_DIR}/scripts/ddl.py --schema=sales --name=fact_orders
PYTHON ${CLAUDE_SKILL_DIR}/scripts/ddl.py --type=view --schema=sales --name=v_daily_revenue
PYTHON ${CLAUDE_SKILL_DIR}/scripts/ddl.py --type=schema --name=sales
PYTHON ${CLAUDE_SKILL_DIR}/scripts/ddl.py --type=database
PYTHON ${CLAUDE_SKILL_DIR}/scripts/ddl.py --type=udf --schema=public
PYTHON ${CLAUDE_SKILL_DIR}/scripts/ddl.py --type=group
table_info.py — 表元数据
单个表的详细统计信息:大小、行数、分布偏斜、编码、排序键性能。
PYTHON ${CLAUDE_SKILL_DIR}/scripts/table_info.py --schema=sales --table=fact_orders
tablename row_count size_mb pct_used diststyle sortkey1 unsorted stats_off
----------------- ---------- ------- -------- ----------- ---------- -------- ---------
sales.fact_orders 85000000 45000 5.8600 KEY(cust_id) order_date 12.50 0.00
search.py — 搜索对象
按名称模式查找表或列(不区分大小写)。当你不知道确切名称时很有用。
PYTHON ${CLAUDE_SKILL_DIR}/scripts/search.py --pattern=order
PYTHON ${CLAUDE_SKILL_DIR}/scripts/search.py --pattern=revenue --type=column
sample.py — 样本数据
快速查看实际行数据。编写复杂查询前务必先执行此操作——这有助于你了解列值、格式和可空性。
PYTHON ${CLAUDE_SKILL_DIR}/scripts/sample.py --schema=sales --table=dim_customers --limit=5
space.py — 磁盘使用情况
查找最大的表,可按架构筛选。
PYTHON ${CLAUDE_SKILL_DIR}/scripts/space.py --schema=sales --top=5
schemaname tablename size_mb row_count pct_used
---------- ---------------- ------- ---------- --------
sales fact_orders 45000 85000000 5.8600
sales fact_line_items 32000 420000000 4.1700
...
profile.py — 数据分析(通过 Redshift)
运行单个 Redshift 查询,计算每列的统计信息。在分析前了解数据质量时很有用。
PYTHON ${CLAUDE_SKILL_DIR}/scripts/profile.py --schema=sales --table=dim_customers
column_name data_type total_rows null_count null_pct distinct_count min_val max_val avg_val
-------------- ----------------- ---------- ---------- -------- -------------- --------- --------- -------
customer_id CHARACTER VARYING 250000 0 0.0 250000 C0001 C250000
customer_name CHARACTER VARYING 250000 12 0.0 249500 Aaron Zoe
signup_date DATE 250000 0 0.0 3650 2015-01-01 2025-12-31
lifetime_value NUMERIC 250000 1500 0.6 48000 0.00 125000.00 2340.50
analyze.py — 本地分析(不使用 Redshift)
在本地分析之前保存的 CSV/JSON 文件。无需网络访问——适合后续分析,避免再次访问集群。
PYTHON ${CLAUDE_SKILL_DIR}/scripts/analyze.py ~/redshift-exports/query-*.csv --describe
PYTHON ${CLAUDE_SKILL_DIR}/scripts/analyze.py data.csv --sum=revenue
PYTHON ${CLAUDE_SKILL_DIR}/scripts/analyze.py data.csv --group-by=region --sum=sales
PYTHON ${CLAUDE_SKILL_DIR}/scripts/analyze.py data.csv --filter='year=2024' --sort=amount --desc --top=10
PYTHON ${CLAUDE_SKILL_DIR}/scripts/analyze.py data.csv --hist=price
可用操作:--count、--describe、--sum=COL、--avg=COL、--min=COL、--max=COL、--median=COL、--group-by=COL、--filter=EXPR、--sort=COL、--desc、--top=N、--hist=COL
只读防护措施
两层保护:
-
你必须验证——将任何 SQL 传递给
query.py之前,请确认第一个关键字在允许列表中。如果用户要求运行会修改数据的查询,请拒绝并说明原因。 -
lib/client.py会强制执行——脚本本身会在 SQL 到达 AWS 之前拒绝不在允许列表中的 SQL。这是一项无法绕过的硬性防护措施。
允许: SELECT、WITH、SHOW、DESCRIBE、EXPLAIN、SET
禁止: CREATE、ALTER、DROP、TRUNCATE、INSERT、UPDATE、DELETE、MERGE、COPY、UNLOAD、GRANT、REVOKE、CALL、EXECUTE、VACUUM、ANALYZE
多语句查询(; 后跟另一条语句)也会被阻止。
内置 SQL
该技能随附从 amazon-redshift-utils 管理视图中提取的 SQL,位于 ${CLAUDE_SKILL_DIR}/scripts/sql/。这些 SQL 可直接查询系统目录——无需管理架构。ddl.py 使用它们生成完整 DDL,包括分布键、排序键、编码、约束和注释。
高级 SQL 模板
通过 query.py 进行临时探索:
查询历史记录(最近 20 条):
SELECT query, TRIM(querytxt) AS sql, starttime, endtime,
DATEDIFF(ms, starttime, endtime) AS duration_ms
FROM stl_query WHERE userid > 1
ORDER BY starttime DESC LIMIT 20
正在运行的查询:
SELECT user_name, db_name, query, pid, starttime, duration, status
FROM stv_recents WHERE status = 'Running'
ORDER BY starttime DESC
表依赖关系(外键关系):
SELECT n1.nspname || '.' || c1.relname AS source_table,
n2.nspname || '.' || c2.relname AS referenced_table,
con.conname AS constraint_name
FROM pg_constraint con
JOIN pg_class c1 ON con.conrelid = c1.oid
JOIN pg_namespace n1 ON c1.relnamespace = n1.oid
JOIN pg_class c2 ON con.confrelid = c2.oid
JOIN pg_namespace n2 ON c2.relnamespace = n2.oid
WHERE con.contype = 'f'
ORDER BY source_table