mcpField
R
redshift

redshift

github.com/onsen-aiデータ・データベース438 回インストール1 週間前に更新
リポジトリ

redshift について

redshift は、AI コーディングエージェント向けの読み取り専用 Redshift 探索・業務分析スキルです。AWS Data API を使い、プロビジョンドクラスターと Redshift Serverless、複数の名前付き接続に対応します。

主な機能

  1. 01読み取り専用 SQL クエリ
  2. 02スキーマ、テーブル、列の閲覧
  3. 03DDL とテーブルメタデータの確認
  4. 04オブジェクト検索とデータサンプル
  5. 05データプロファイルとディスク使用量の確認
  6. 06クエリ結果の CSV 保存

活用シーン

  1. 01不慣れな Redshift スキーマの調査
  2. 02SQL による業務指標の分析
  3. 03テーブルサイズとストレージ使用量の確認
  4. 04保存済みクエリ結果のローカル分析

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/onsen-ai/redshift-skill --skill redshift

インストール後、Claude Code で/redshiftを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

.DS_Store
.gitignore
LICENSE
README.md
scripts/
.DS_Store
columns.py
ddl.py
analyze.py
profile.py
schemas.py
space.py
query.py
search.py
sample.py
setup.py
table_info.py
tables.py
scripts/lib/
__init__.py
client.py
formatter.py
scripts/sql/
extended_table_info.sql
generate_external_tbl_ddl.sql
generate_database_ddl.sql
generate_schema_ddl.sql
generate_udf_ddl.sql
generate_group_ddl.sql
generate_tbl_ddl.sql
space_used_per_tbl.sql
generate_view_ddl.sql
tests/
test_config.py

詳細

Redshift スキル

AWS Data API を使った、読み取り専用の Redshift 調査とビジネス分析です。プロビジョニング済みクラスターと Redshift Serverless の両方に対応しています。クロスプラットフォーム(Mac + Windows)で、あらゆる AI コーディングエージェントで利用できます。

すべてのスクリプトは ${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 では python3 の代わりに python を使用してください)

クエリを実行する前に、セットアップが完了したことをユーザーが確認するまで待ちます。

接続の選択

このスキルは複数の名前付き接続(AWS アカウントごとに 1 つなど)に対応しています。設定形式は次のとおりです。

{
  "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 という 1 つの接続として読み込まれます。

ユーザーがアカウント、クラスター、またはプロジェクトを指定した場合は、対応する接続を選び、すべての呼び出しに --connection NAME を渡します。指定がない場合はデフォルトを使用し、どの接続を使用したか伝えます。

クイックリファレンス

タスクスクリプト使用する場面主な引数
SQL の実行query.py任意の読み取り専用クエリを実行する"SELECT ..." または --sql-file=PATH
スキーマの一覧表示schemas.py最初の確認 — 存在するスキーマを確認する
テーブルの一覧表示tables.pyテーブルを参照し、クエリ実行前に行数とサイズを確認する--schema=NAME
カラムの一覧表示columns.pyカラムの型、エンコーディング、分散キー/ソートキーを把握する--schema=NAME --table=NAME
テーブル DDLddl.pyエンコーディング、分散キー、ソートキーを含む完全な CREATE TABLE を取得する--schema=NAME --name=NAME
ビュー DDLddl.pyCREATE VIEW の定義を取得する--type=view --schema=NAME --name=NAME
スキーマ DDLddl.py承認情報を含む CREATE SCHEMA を取得する--type=schema [--name=NAME]
データベース DDLddl.pyCREATE DATABASE を取得する--type=database
UDF DDLddl.py関数定義(SQL + Python)を取得する--type=udf [--schema=NAME]
外部 DDLddl.pySpectrum 外部テーブルの DDL を取得する--type=external [--schema=NAME]
グループ DDLddl.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カラムごとの統計(NULL 数、カーディナリティ、最小値/最大値/平均値)を取得する--schema=NAME --table=NAME
ローカル分析analyze.pyRedshift にアクセスせず、保存済みの結果をローカルで分析する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=NAMEAWS プロファイルを上書きします
--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)。SQL クエリも対応する .sql ファイルとして保存するには、--save-sql を使用します。自動保存をスキップするには、--no-save を使用します。特定の場所に保存するには、--save=PATH を使用します。


防御的ガードレール

これらのルールは、高コストなクエリからクラスターを保護します。ルールに従いつつ、状況に応じて判断してください。ユーザーがルールに反する操作を明示的に求めた場合は、トレードオフを説明し、確認を得てから進めてください。

  • 1 万行を超えるテーブルに対して、決して SELECT * を実行しないでください — このツールはデータのエクスポートではなく、調査と分析のためのものです。代わりに、集計、フィルター、または sample.py を使用してください。小さなテーブルであれば、SELECT * を使用しても問題ありません。
  • 不慣れなテーブルを調べるときは、必ず LIMIT を追加してください(デフォルトの LIMIT は 100 です)。
  • 最初に行数を確認してください — クエリを作成する前に tables.py --schema=X を実行し、対象の規模を把握してください。
  • 大きなテーブルでは集計を優先してください — 生データを取得するより、GROUP BY を使った COUNT、SUM、AVG を使用してください。小さなテーブルや、データの調査・理解を目的とする場合は、生データを取得しても問題ありません。
  • 非常に大きなファクトテーブルではソートキーでフィルターしてください — 特に、特定の期間で絞り込む際に日付/タイムスタンプでソートされたテーブルが対象です。Redshift はゾーンマップを使ってブロックをスキップするため、日付範囲によるフィルターは非常に効率的です。必須ではありませんが、1 億行を超えるテーブルでは強く推奨されます。
  • 結合は問題ありません — 結合条件が正しく、結果を適切に集計またはフィルターすれば、Redshift は大きなテーブル同士の結合をうまく処理できます。リスクは結合そのものではなく、結合結果から上限のない生データを返すことです。
  • 意図しないクロス結合を避けてください — 意図的に直積(例:設計上のデータ展開)が必要な場合を除き、必ず ON/USING を指定してください。
  • 調査時は、上限のない SELECT よりも、LIMIT と ORDER BY を組み合わせて使用してください。

サイズを考慮した使い分け:

テーブルのサイズ方針
1 万行未満自由に調査できます。SELECT * を使用しても問題ありません
1 万~100 万行WHERE または LIMIT を追加します。テーブル全体を対象とするクエリでは集計を優先します
100 万行超必ず集計またはフィルターを行い、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 をインラインで記述する: SQL ファイルの作成とクエリの実行を 1 回の Bash 呼び出しで行うには:

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' で引用符を付けると、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 ファイルがすでにあり、特定の値(例:対象期間を 1 週間先にずらす)だけを変更する場合は、LLM のコンテキスト内でファイル全体を書き直すのではなく、1 行のコマンドで値を置き換えます:

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 は左揃えにする
  • 1 行に 1 列 — 複数の列を 1 行にまとめてはいけません。各列の式は、AS エイリアスとともにそれぞれ別の行に記述します。
  • 列エイリアスの AS は、一定の位置に揃える
  • 自明ではないビジネスロジックを説明するインラインコメントを付ける
  • CTE 名は技術的な処理ではなく、ビジネス上の概念を表すものにする
コメントを十分に付ける

すべてのクエリに、何をするかだけでなく、なぜそうするかを説明するコメントを含めます。SQL は、次に読む人(または次のエージェント)のためのドキュメントとして扱います。

  • すべてのクエリの先頭にヘッダーブロックを置く:目的、データソース、主要な前提条件、パラメーター
  • 論理ブロック(例:実績、予算、ピボット 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。


スキーマ探索ワークフロー

不慣れなスキーマを調べる際は、段階的に次の手順を進めてください。この手順に厳密に従う必要はありません。ユーザーの意図が明確で具体的な場合は、該当する手順へ直接進んでください。可能な場合は、手順を並行して進めてください。

  1. 全体像を把握する — schemas.py → どのようなスキーマがあるか確認します
  2. テーブルを確認する — tables.py --schema=X → 行数とサイズを確認します
  3. 構造を把握する — columns.py --schema=X --table=Y → 列の型とキーを確認します
  4. メタデータを確認する — table_info.py → 分布、ソートキー、未ソートの割合を確認します
  5. まずサンプルを確認する — sample.py --limit=5 → 実際のデータ値を確認します
  6. 必要に応じてプロファイルする — profile.py → 列ごとの NULL、カーディナリティ、最小値/最大値を確認します
  7. 目的に合わせたクエリを書く — これで、安全かつ効率的な SQL を書くための情報がそろいます
  8. ローカルで分析する — 保存した結果を analyze.py で追加分析します

近道: ユーザーが「先月の注文数は?」と尋ねた場合、探索用スクリプトを6つ実行する必要はありません。テーブルのサイズを確認し、クエリを書いて実行してください。


ビジネス分析のワークフロー

一般的なビジネス上の質問に取り組む際のパターンです。プロダクトアナリスト、コマーシャルアナリスト、または BI 開発者の視点で考えてください。

ビジネスパフォーマンスを把握する
  1. 主要指標から始める — 対象期間の総売上、注文数、顧客数
  2. ディメンションごとに分解する — 時間(日次/週次/月次)、地域、チャネル、商品カテゴリ
  3. 期間を比較する — 今月と先月、今年と昨年、前年の同期間との比較
  4. 外れ値を特定する — 期待値を大きく上回る、または下回るセグメントはどれか?
根本原因分析

何かがおかしいと思われる場合(「先週、売上が15%減少した」など):

  1. 異常を確認する — これは実際に起きていることか?データソースを確認し、ほかの指標と比較します
  2. 指標を分解する — 数量(注文数の減少)によるものか、金額(平均注文額の低下)によるものか?
  3. ディメンションごとに絞り込む — どの地域/チャネル/カテゴリが変化の要因か?
  4. 外れ値を詳しく調べる — そのセグメントで何が変わったか?新商品か、価格設定か、在庫の問題か?
  5. イベントと照合する — プロモーションの開始/終了、価格変更、在庫切れ、季節性
よくある分析パターン
パターンアプローチ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 — サンプルデータ

実際の行データを手軽に確認できます。複雑なクエリを書く前に、必ず実行してください。列の値、形式、NULL 許容性を把握するのに役立ちます。

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


読み取り専用のガードレール

保護は2層になっています:

  1. 検証が必要です — query.py に SQL を渡す前に、最初のキーワードが許可リストに含まれていることを確認してください。ユーザーが変更を伴うクエリの実行を求めた場合は、拒否して理由を説明してください。

  2. lib/client.py による強制 — スクリプト自体が、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/ に含まれています。これらはシステムカタログに対して直接実行されるため、管理スキーマは不要です。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

テーブルの依存関係(FK リレーションシップ):

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

コメント