RedshiftServerlessにDataAPIでクエリを投げてみた

2022.11.01

RedshiftServerlessが発表されて数ヶ月経ちましたが、 みなさんクエリはどうやって投げているでしょうか? 多くの方が、マネジメントコンソールから開けるクエリエディタをお使いかと思います。 私もそうです。

とはいえ、私はターミナルで作業していることが多く、 どんな出力内容もすぐVimで開きたがってしまう習性を持っています。 ということで、RedshiftServerlessに対してもDataAPIを使ってクエリを投げていきたいと思います。 AWS CLIで試したところ、とっても簡単にできました。

DataAPIの基本的な使い方についてはこちらのブログをご参照ください。

サブネットもセキュリティグループも考慮不要!Lambda関数からData API for Redshiftでクエリ実行してみた。

投げ方の確認

RedshiftServerlessにDataAPIでクエリを投げる方法については ドキュメント に記述がありますが、

Amazon Redshift Data API を使用して、Amazon Redshift Serverless に接続することもできます。AWS CLI の呼び出しでは、cluster-identifier パラメータではなく、workgroup-name パラメータを使用します。

しか書かれておらず、かなりシンプルです。 従来のクラスタを指定する cluster-idnetifier に変わって、 RedshiftServerlessのワークグループを指定するというだけのようです。

めちゃくちゃ簡単ですね。

AWS CLIで投げてみる

AWS CLIでクエリを投げてみたいと思います。

まず確認しなければいけないのはAWS CLIのバージョンです。 RedshiftServerlessは新しい機能なので、かなり新しいバージョンのAWS CLIが必要です。

私の環境に入っていた

$ aws --version
aws-cli/2.2.25 Python/3.8.8 Darwin/21.6.0 exe/x86_64 prompt/off

ではダメで

$ aws --version
aws-cli/2.8.5 Python/3.9.11 Darwin/21.6.0 exe/x86_64 prompt/off

なら使用することができました。

最新バージョンのAWS CLIを入れる

私はMacで試したのですが、

「AWS CLI の最新バージョンをインストールまたは更新します。」 に従うだけでバージョンアップができました。

「macOS」→「Command line installer - All users」にある通り、

$ curl "https://awscli.amazonaws.com/AWSCLIV2.pkg" -o "AWSCLIV2.pkg"
$ sudo installer -pkg AWSCLIV2.pkg -target /

を実行するだけでした。

実行してみる

実際に実行してみます。

まずはクエリを発行します。 単純にclsuter-identifierworkgroup-nameに変更してみます。

$ aws redshift-data execute-statement --workgroup-name sample-dev-redshift-wg --database sample-db --db-user admin --sql "select count(*) from public.mst_example01"
An error occurred (ValidationException) when calling the ExecuteStatement operation: DbUser cannot be set during a serverless request

怒られました。 RedshiftServerlessの場合はDbUserは指定できないようです。 ここは詳細を調べてはいないのですが、従来のクラスタ版とクエリするユーザの考え方に違いがあるようです。 従来クラスタでは、DataAPIではRedshiftに存在するユーザとしてクエリを投げますが、 RedshiftServerlessではIAMによる認証とクエリを投げるユーザは一意に紐づいているように見えます。 ということで、RedshiftServerlessの場合はdb-userの指定も不要になって、以下のようにクエリが投げられるようです。

$ aws redshift-data execute-statement --workgroup-name sample-dev-redshift-wg --database sample-db --sql "select count(*) from public.mst_example01"
{
    "CreatedAt": 1667235325.346,
    "Database": "sample-db",
    "DbUser": "IAMR:cm-hirano.shigetoshi",
    "Id": "c54ad442-bd2c-463f-9e27-97f5856053d5",
    "WorkgroupName": "sample-dev-redshift-wg"
}

DataAPIでのクエリは非同期処理ですので、返ってきたIdを使って結果を取りに行きます。

$ aws redshift-data get-statement-result --id c54ad442-bd2c-463f-9e27-97f5856053d5
{
    "Records": [
        [
            {
                "longValue": 12
            }
        ]
    ],
    "ColumnMetadata": [
        {
            "isCaseSensitive": false,
            "isCurrency": false,
            "isSigned": true,
            "label": "count",
            "length": 0,
            "name": "count",
            "nullable": 1,
            "precision": 19,
            "scale": 0,
            "schemaName": "",
            "tableName": "",
            "typeName": "int8"
        }
    ],
    "TotalNumRows": 1
}

無事テーブルの行数(12行)が取れました!

おまけ: Python boto3で利用する

boto3でクエリを投げる様子も記載しようかと思いましたが、 事情は全て同じだったので特に書くことはありませんでした。

boto3が古い場合は新しいバージョンにして、 ClusterIdentifierの代わりにWorkgroupNameを指定するだけです。 DbUserについてはやはり指定不要です。

おまけ: redshiftコマンドも更新しました

以前作成したredshiftコマンドもServerlessに対応するように修正しました。

[Redshift] DataAPIを使ってpsqlっぽくSQL実行するコマンドを作ってみた。

スクリプト

-Wまたは--workgroup_nameが指定された場合にはRedshiftServerlessだと判断してクエリを投げます。

まとめ

RedshiftServerlessでも従来のクラスタとほとんど同じやり方でDataAPIが使えることがわかりました。 Serverlessなのでクラスタが立っているかの確認もなく、ターミナル画面からサクッとクエリが投げられますね。 (ただし料金には注意)