mcpField
R
redshift-api

redshift-api

github.com/anthropics数据与数据库7439 次安装3 周前更新
代码仓库

关于 redshift-api

为 Amazon Redshift Data API 查询与管理操作提供指南和脚本的技能,适用于需要通过 Data API 执行 SQL 的数据工作流。它将异步提交、状态轮询和分页取回结果串联起来,也覆盖目录浏览、批量语句与取消操作。

主要功能

  1. 01提交 SQL 并轮询执行状态
  2. 02分页获取并解码查询结果
  3. 03按 ID 恢复语句并取消运行
  4. 04在事务中执行多条语句
  5. 05浏览数据库、模式、表和列

适用场景

  1. 01运行并获取大型查询的分页结果
  2. 02查询超时后通过语句 ID 恢复
  3. 03检查表结构或批量执行事务语句

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/anthropics/claude-tag-plugins --skill redshift-api

安装后在 Claude Code 中输入/redshift-api确认已加载。

附带文件references/api.mdscripts/rs_query.sh

详细介绍

在 Amazon Redshift Data API 中,每次调用都是向 https://redshift-data.<region>.amazonaws.com/ 发送 POST 请求,并带上 Content-Type: application/x-amz-json-1.1 和 X-Amz-Target: RedshiftData.<Action>——它没有 REST 风格的路径。该 API 完全采用异步方式:提交语句,获取 Id,轮询 DescribeStatement 直到完成,然后通过 GetStatementResult 分页获取结果—— scripts/rs_query.sh(操作 1)会替你完成这一流程。相同的调用适用于预置集群和 Serverless;只有连接目标字段不同。

请求设置

身份验证由运行时处理——对此 API 的请求会使用为工作区配置的凭证进行签名,因此无需进行任何设置。请勿尝试获取 AWS 密钥或自行对请求签名。如果持续出现 AccessDeniedException,说明尚未为此工作区配置凭证——应报告这一情况,而不是排查身份验证问题。

有两项实际必需的配置:

1. 区域——它是端点主机名的一部分:

export AWS_DEFAULT_REGION="us-east-1"        # the region your cluster / workgroup is in

2. 连接目标——Data API 要连接的集群/工作组和数据库。选择一种方式,并将对应的 JSON 字段填入 RS_TARGET;以下示例会将其合并到每个请求正文中:

  • Serverless——传入 WorkgroupName。配置的身份会映射到数据库用户。 最简单。
  • 预置集群,临时凭证——传入 ClusterIdentifier 和 DbUser。Data API 会在后台解析数据库凭证。
  • 预置集群或 Serverless,使用 Secrets Manager——传入指向包含数据库登录信息的密钥的 SecretArn。

根据实际情况设置一次:

export RS_DATABASE="dev"
# Serverless:
export RS_TARGET='{"WorkgroupName": "my-workgroup"}'
# — or provisioned + temp creds:
# export RS_TARGET='{"ClusterIdentifier": "my-cluster", "DbUser": "my_user"}'
# — or either + Secrets Manager:
# export RS_TARGET='{"ClusterIdentifier": "my-cluster", "SecretArn": "arn:aws:secretsmanager:us-east-1:123456789012:secret:rs-creds-AbCdEf"}'

下文使用的辅助函数。 一个函数封装了端点、请求头和操作名称。Authorization 请求头是占位符——运行时会将其替换为真实签名。

rsapi() {
  local action="$1"
  curl -sS "https://redshift-data.${AWS_DEFAULT_REGION}.amazonaws.com/" \
    -H "Content-Type: application/x-amz-json-1.1" \
    -H "X-Amz-Target: RedshiftData.${action}" \
    -H "Authorization: placeholder" \
    -d "${2:?rsapi needs a JSON body as the second argument}"
}

基本检查——列出数据库。200 响应中包含 Databases 数组,表明工作区配置正常且连接目标正确。错误信息会指出失败的环节。

rsapi ListDatabases "$(jq -n --argjson t "$RS_TARGET" --arg db "$RS_DATABASE" \
  '$t + {Database: $db}')" | jq .

核心操作

每项连接数据库的操作都使用相同的合并目标正文—— $t + {Database: $db, ...}。错误会以 {"__type": "<Exception>", "message": "..."} 的形式返回,而不是预期的结构;对于任何调用,如果顶层字段(Id、Status、Records 等)缺失,就说明收到的是错误封装——打印错误并停止。

1. 运行查询(scripts/rs_query.sh)

通过捆绑的脚本运行 SQL(路径相对于此技能目录):脚本使用 ExecuteStatement 提交语句,轮询 DescribeStatement 直到进入终止状态,通过 NextToken 对 GetStatementResult 的结果分页,并解码带类型的单键单元格对象。

scripts/rs_query.sh \
  'SELECT event_name, COUNT(*) AS n FROM public.events
   WHERE event_date >= :start GROUP BY 1 ORDER BY 2 DESC LIMIT 20' \
  --param start=2024-01-01 --name top-events
  • SQL 是一个参数(也可通过标准输入传入)。实例相关配置来自上文的 AWS_DEFAULT_REGION / RS_TARGET / RS_DATABASE;--database 可覆盖数据库。
  • --param NAME=VALUE(可重复使用)用于绑定 :NAME 占位符——值始终是字符串,由数据库进行类型转换。--name 用于设置 StatementName,让查询显示在 ListStatements 中。
  • --max-rows N 限制获取的行数(默认为 10000,0 = 全部);--json 会为每行输出一个 JSON 对象,而不是带表头的 TSV。语句 ID、状态、耗时和行数会输出到 stderr。
  • 退出码:0 表示成功;1 表示提交失败或 SQL 状态为 FAILED/ABORTED(API 自身的消息会输出到 stderr);2 表示等待超过 --max-wait 秒后放弃(默认为 600)——语句 ID 会输出到 stderr;使用操作 2 恢复执行。

如果脚本报错,请阅读脚本——它只是普通的 curl + jq——并参照 references/api.md 进行排查。 如需使用 BatchExecuteStatement 和子语句结果、复用会话(SessionKeepAliveSeconds / SessionId)、ResultFormat: CSV、取消操作或浏览目录,请使用下方的操作。

2. 按 ID 恢复语句(DescribeStatement → GetStatementResult)

当脚本以状态码 2(超时)退出,或你从其他地方获取了语句 ID 时,可直接轮询并获取结果:

rsapi DescribeStatement "$(jq -n --arg id "$ID" '{Id: $id}')" \
  | jq '{Status, Duration, ResultRows, HasResultSet, Error}'
rsapi GetStatementResult "$(jq -n --arg id "$ID" '{Id: $id}')" \
  | jq -r '.Records[]? | [.[] | if .isNull then null else to_entries[0].value end] | @tsv'
  • Status ∈ SUBMITTED、PICKED、STARTED、FINISHED、FAILED、ABORTED。只有 FINISHED 且 HasResultSet: true 时才有行;FAILED 会在 .Error 中包含 SQL 错误。Duration 的单位是纳秒。
  • 结果单元格是带有一个键的类型化对象(参见“错误处理”中的注意事项);列名和类型位于第一页的 .ColumnMetadata 中。后续页面通过 NextToken 获取——没有页面大小设置项;DescribeStatement.ResultRows 会预先给出总行数。
3. 取消正在运行的语句(CancelStatement)
rsapi CancelStatement "$(jq -n --arg id "$ID" '{Id: $id}')" | jq .
# {"Status": true} on success — best-effort, check DescribeStatement to confirm.
4. 在一次调用中运行多条语句(BatchExecuteStatement)

所有语句在同一事务中运行——要么全部提交,要么全部回滚。

rsapi BatchExecuteStatement "$(jq -n --argjson t "$RS_TARGET" --arg db "$RS_DATABASE" '$t + {
    Database: $db,
    Sqls: ["CREATE TEMP TABLE tmp AS SELECT 1 AS x", "SELECT * FROM tmp"]
  }')" | jq '{Id}'

对父级 Id 调用 DescribeStatement 会返回一个 SubStatements[] 数组。每条子语句都有自己的 Id(父级 ID 后缀为 :1、:2、……)、Status 和 HasResultSet——分别调用各自的 GetStatementResult 获取子语句结果。

5. 列出最近的语句(ListStatements)
rsapi ListStatements '{"MaxResults": 20, "Status": "ALL"}' \
  | jq '.Statements[] | {Id, StatementName, Status, QueryString: (.QueryString[0:80]), CreatedAt}'

Status 筛选条件:SUBMITTED、PICKED、STARTED、FINISHED、FAILED、ABORTED、ALL——如果省略该参数,只会列出已完成的语句。MaxResults 为 0–100。RoleLevel 默认为 true(包括任何使用相同 IAM 角色的人的语句);设为 false 可仅查看当前会话的语句。

6. 浏览目录(ListDatabases / ListSchemas / ListTables / DescribeTable)

这四项操作都使用合并后的目标请求体。模式使用 SQL LIKE 通配符(%、_)。

  • ListDatabases — Databases[](字符串)
  • ListSchemas — SchemaPattern(可选)— Schemas[](字符串)
  • ListTables — SchemaPattern、TablePattern — Tables[] {schema, name, type} — type ∈ TABLE/VIEW/SYSTEM TABLE/GLOBAL TEMPORARY/LOCAL TEMPORARY/ALIAS/SYNONYM
  • DescribeTable — Schema、Table — ColumnList[] {name, typeName, nullable, length, precision}
rsapi ListTables "$(jq -n --argjson t "$RS_TARGET" --arg db "$RS_DATABASE" \
  '$t + {Database: $db, SchemaPattern: "public", TablePattern: "ev%"}')" | jq '.Tables'

JSON 字段名采用 PascalCase(WorkgroupName,而非 workgroup-name)。这四项操作都支持分页(NextToken)。各操作请求体的完整格式请参见 references/api.md。

分页

GetStatementResult、ListStatements、ListDatabases、ListSchemas、ListTables 和 DescribeTable 都采用相同的分页方式:如果还有更多结果,响应中会包含 NextToken;在下一次请求体中将其作为 NextToken 传回。没有该字段时即停止。

速率限制

  • 活动语句 — 每个集群或工作组最多允许 500 条活动语句(SUBMITTED/STARTED)。超出后,提交会失败并返回 ActiveStatementsExceededException。
  • 结果大小 — 每条语句最多 500 MB(gzip 压缩后),每行最多 64 KB。结果过大时会失败;请添加 LIMIT,或使用 UNLOAD ... TO 's3://...'。
  • 结果保留时间 — 24 小时;此后,GetStatementResult 会返回 ResourceNotFoundException。
  • 语句时长 — 最长 24 小时。查询字符串 — 最长 100 KB。
  • API 速率 — 每个账户/区域的 TPS 配额固定,无法调整:DescribeStatement 为 100,ExecuteStatement 为 30,GetStatementResult 为 20,BatchExecuteStatement 为 20;而 CancelStatement、ListStatements、ListDatabases、ListSchemas、ListTables、DescribeTable 仅为 3 TPS。超出配额会返回 ThrottlingException(HTTP 400)——请降低请求频率,不要在紧密循环中轮询。

错误处理

错误以 {"__type": "<Exception>", "message": "..."} 的形式返回(HTTP 400/403/500)。__type 字段是判别字段。

  • ValidationException (400) — 参数错误。常见情况:同时传入 ClusterIdentifier 和 WorkgroupName,或两者都未传入;缺少 Database;字段大小写错误。
  • ActiveStatementsExceededException (400) — 正在执行的语句过多。ListStatements {"Status":"STARTED"} 会显示正在运行的语句。
  • ActiveSessionsExceededException (400) — 打开的会话超过 500 个。不要再传入 SessionKeepAliveSeconds,或等待空闲会话过期。
  • ExecuteStatementException (500) — 数据库收到请求前提交就已失败——集群或工作组名称错误、集群不可达、DbUser 错误。检查 RS_TARGET。
  • ResourceNotFoundException (400) — 语句 ID 未知或已超过 24 h。
  • BatchExecuteStatementException (500) — 批次中的某条语句失败;整个事务已回滚。检查 SubStatements[].Error。
  • DatabaseConnectionException / QueryTimeoutException — 目录调用无法连接数据库或超时。检查目标是否正常运行;然后重试。
  • AccessDeniedException (403) — 凭证需要对集群/工作组 ARN 具有 redshift-data:* 权限,此外还需根据连接模式具有 redshift:GetClusterCredentials / redshift-serverless:GetCredentials / secretsmanager:GetSecretValue 权限。请说明缺少哪项权限。
  • InternalServerException (500) — 除非传入 ClientToken,否则 ExecuteStatement 不具备幂等性——重试写入前先检查 ListStatements。
  • DescribeStatement 中出现 Status: FAILED — 提交后 SQL 执行失败。读取 .Error 获取 SQL 错误信息。

两个易错之处:

  • ExecuteStatement 返回 200 ≠ 查询成功。 SQL 错误只会在之后 DescribeStatement 中显示为 Status: FAILED。获取结果前务必先轮询状态。
  • 单元格值是带类型的单键对象,而不是裸值。longValue 是 JSON 数字, isNull: true 则是另一种独立结构。简单读取 .value 会得到空值,而在带类型的键之间串联 jq // 会在遇到 false/0 时出错。请使用 to_entries[0].value。

深入了解

references/api.md 包含完整目录——每个操作的 PascalCase 请求/响应结构(用于原始 HTTP)、SqlParameter 绑定格式、ColumnMetadata 字段、批次的 SubStatementData、会话复用(SessionKeepAliveSeconds / SessionId)以及配额表。需要使用上述内容未涵盖的操作,或了解原始 HTTP 请求体的精确结构时,请阅读该文档。

评论

支持 Markdown