百名山 API を開発しました | mountix APICLICK !

AWS SDK for RustでDynamoDBのデータをScanする

  • URLをコピーしました!

AWS SDK for Rust の Developer Preview が発表されました。

examplesにDynamoDB操作関連のソースコードが載っているので
いくつか触ってみたいと思います。

今回は scan を試します。

AWS SDK for Rust を使ってみる

  1. scan のサンプルを実行
  2. scan結果のレスポンスを解析

Developer Preview のため、本番環境での使用は避けたほうが無難でしょう。

目次

Scanでデータを取得する

検証環境

  • macOS:Big Sur 11.6
  • Rust:1.57.0
  • AWS SDK for Rust:v0.2.0

環境変数の設定

認証情報の取得は環境変数からおこなうため、以下の環境変数を設定します。

  • AWS_DEFAULT_REGION
  • AWS_SECRET_ACCESS_KEY
  • AWS_ACCESS_KEY_ID

詳しくは、README で確認してください。

テーブルの作成

DynamoDBに Users テーブルを作成し、スラムダンク 湘北高校のメンバーを登録します。

  • テーブル名:Users
  • パーティションキー:Id(Number)
  • ソートキー:なし
{
    "users": [
        {
            "Id": 1,
            "Name": "桜木花道",
            "Grade": 1,
            "Position": "PF",
            "Number": 10,
            "Height": 189,
            "Weight": 83
        },
        {
            "Id": 2,
            "Name": "流川楓",
            "Grade": 1,
            "Position": "SF",
            "Number": 11,
            "Height": 187,
            "Weight": 75
        },
        {
            "Id": 3,
            "Name": "赤木剛憲",
            "Grade": 3,
            "Position": "C",
            "Number": 4,
            "Height": 197,
            "Weight": 93
        },
        {
            "Id": 4,
            "Name": "宮城リョータ",
            "Grade": 2,
            "Position": "PG",
            "Number": 7,
            "Height": 168,
            "Weight": 59
        },
        {
            "Id": 5,
            "Name": "三井寿",
            "Grade": 3,
            "Position": "SG",
            "Number": 14,
            "Height": 184,
            "Weight": 70
        },
        {
            "Id": 6,
            "Name": "木暮公延",
            "Grade": 3,
            "Position": "SF",
            "Number": 5,
            "Height": 178,
            "Weight": 62
        }
    ]
}

scanでデータを全件取得する

Cargo.toml

依存クレートを設定します。

[dependencies]
aws-config = "0.2.0"
aws-sdk-dynamodb = "0.2.0"
tokio = { version = "1", features = ["full"] }

main.rs

use aws_sdk_dynamodb::{Client};

#[tokio::main]
async fn main() {
    let config = aws_config::load_from_env().await;
    let client = Client::new(&config);

    let resp = client.scan().table_name("Users").send().await;
    match resp {
        Ok(scan_output) => {
            if let Some(items) = scan_output.items {
                for item in items {
                    println!("{:?}", item);

                    // Idを取り出す
                    if let Some(attr_val) = item.get("Id") {
                        if let Ok(id_val) = attr_val.as_n() {
                            if let Ok(id) = id_val.parse::<u32>() {
                                println!("{}", id);
                            }
                        }
                    }

                    // Nameを取り出す
                    if let Some(attr_val) = item.get("Name") {
                        if let Ok(name) = attr_val.as_s() {
                            println!("{}", name.to_string());
                        }
                    }
                }
            }
        },
        Err(e) => {
            println!("{}", e);
        }
    }
}

環境変数に設定した認証情報を取得するため、configを生成します。
その後、DynamoDBのクライアントを生成します。

.table_name()でテーブル名を指定し、.send()でリクエストを送信します。
非同期メソッドで実装されているため、.awaitが必要です。

Idの取得では.as_n()、Nameの取得では.as_s()を使用しています。

取得結果のId は&Stringであるため、
数値として扱う場合は.parse()等で変換する必要があるので注意です。

以下、実行結果です。

{"Id": N("3"), "Name": S("赤木剛憲"), "Grade": N("3"), "Weight": N("93"), "Height": N("197"), "Position": S("C"), "Number": N("4")}
赤木剛憲
4
{"Id": N("2"), "Number": N("11"), "Position": S("SF"), "Grade": N("1"), "Weight": N("75"), "Name": S("流川楓"), "Height": N("187")}
流川楓
11
{"Height": N("168"), "Weight": N("59"), "Name": S("宮城リョータ"), "Number": N("7"), "Grade": N("2"), "Position": S("PG"), "Id": N("4")}
宮城リョータ
7
{"Position": S("SF"), "Number": N("5"), "Weight": N("62"), "Grade": N("3"), "Name": S("木暮公延"), "Id": N("6"), "Height": N("178")}
木暮公延
5
{"Id": N("1"), "Position": S("PF"), "Height": N("189"), "Number": N("10"), "Grade": N("1"), "Weight": N("83"), "Name": S("桜木花道")}
桜木花道
10
{"Name": S("三井寿"), "Grade": N("3"), "Number": N("14"), "Height": N("184"), "Position": S("SG"), "Id": N("5"), "Weight": N("70")}
三井寿
14

フィルターでデータを絞り込む

フィルターを使い、プライマリーキーやソートキー以外の絞り込み条件を追加することも可能です。

use aws_sdk_dynamodb::model::{AttributeValue};
let resp = client
        .scan()
        .table_name("Users")
        .filter_expression("#filterKey >= :filterValue".to_string())
        .expression_attribute_names("#filterKey".to_string(), "height".to_string())
        .expression_attribute_values(":filterValue".to_string(), AttributeValue::N("180".to_string()))
        .send()
        .await;

まとめ

リクエストを送信するまでの処理は、直感的でわかりやすいと感じました。

レスポンスの解析が面倒で、どうしてもネストが深くなりがちに…
スマートな書き方があれば、教えてください…

著:初田直也, 著:山口聖弘, 著:吉川哲史, 著:豊田優貴, 著:松本健太郎, 著:原将己, 著:中村謙弘, 著:フォルシア株式会社
¥1,782 (2022/10/05 16:03時点 | Amazon調べ)

この記事が気に入ったら
フォローしてね!

  • URLをコピーしました!

コメント

コメントする

目次