【问题标题】:How to query a specific set of attributes from dynamoDB using rust language?如何使用 Rust 语言从 dynamoDB 查询一组特定的属性?
【发布时间】:2022-11-25 21:19:25
【问题描述】:

我是 Rust 的新手,这个问题可能看起来很愚蠢。我正在尝试开发一个拉姆达从中读取单个项目动态数据库给了一把钥匙。返回的项目需要作为调用 lambda 的结果共享回来。

我想要响应为 JSON.

这是我所拥有的:

输入结构

#[derive(Deserialize, Clone)]
struct CustomEvent {
    #[serde(rename = "user_id")]
    user_id: String,
}

输出结构

#[derive(Serialize, Clone)]
struct CustomOutput {
    user_name: String,
    user_email: String,
}

主要功能

#[tokio::main]
async fn main() -> std::result::Result<(), Error> {
    let func = handler_fn(get_user_details);
    lambda_runtime::run(func).await?;
    Ok(())
}

查询的逻辑

async fn get_user_details(
    e: CustomEvent,
    _c: Context,
) -> std::result::Result<CustomOutput, Error> {
    if e.user_id == "" {
        error!("User Id must be specified as user_id in the request");
    }

    let region_provider =
        RegionProviderChain::first_try(Region::new("ap-south-1")).or_default_provider();

    let shared_config = aws_config::from_env().region(region_provider).load().await;
    let client: Client = Client::new(&shared_config);

    let resp: () = query_user(&client, &e.user_id).await?;

    println!("{:?}", resp);

    Ok(CustomOutput {
        // Does not work
        // user_name: resp[0].user_name,
        // user_email: resp[0].user_email,
        // Works because it is hardcoded
        user_name: "hello".to_string(),
        user_email: "world@gmail.com".to_string()

    })
}

async fn query_user(
    client: &Client,
    user_id: &str,
) -> Result<(), Error> {
    let user_id_av = AttributeValue::S(user_id.to_string());

    let resp = client
        .query()
        .table_name("users")
        .key_condition_expression("#key = :value".to_string())
        .expression_attribute_names("#key".to_string(), "id".to_string())
        .expression_attribute_values(":value".to_string(), user_id_av)
        .projection_expression("user_email")
        .send()
        .await?;

    println!("{:?}", resp.items.unwrap_or_default()[0]);

    return Ok(resp.items.unwrap_or_default().pop().as_ref());
}

我的TOML

[dependencies]
lambda_runtime = "^0.4"
serde = "^1"
serde_json = "^1"
serde_derive = "^1"
http = "0.2.5"
rand = "0.8.3"
tokio-stream = "0.1.8"
structopt = "0.3"
aws-config = "0.12.0"
aws-sdk-dynamodb = "0.12.0"
log = "^0.4"
simple_logger = "^1"
tokio = { version = "1.5.0", features = ["full"] }

我无法解包并将响应发送回调用的 lambda。从 query_user 函数,我希望能够将构造的 CustomOutput 结构返回给这个

Ok(CustomOutput {
        // user_name: resp[0].user_name,
        // user_email: resp[0].user_email,
    })

块在 get_user_details 中。任何帮助或参考都会有很大帮助。谢谢你。

【问题讨论】:

    标签: rust amazon-dynamodb aws-sdk dynamodb-queries aws-sdk-rust


    【解决方案1】:

    经过几次尝试,这是我学到的: 可以使用匹配关键字来代替将结果收集到变量中。 我这样做了:

    match client
            .query()
            .table_name("users")
            .key_condition_expression("#key = :value".to_string())
            .expression_attribute_names("#key".to_string(), "id".to_string())
            .expression_attribute_values(":value".to_string(), user_id_av)
            .projection_expression("user_email")
            .send()
            .await
        {
            Ok(resp) => Ok(resp.items),
            Err(e) => Err(e),
        }
    

    当从数据库返回响应时,它必须在其中包含一个项目键值。

    所以, 这一行:

    Ok(resp) => Ok(resp.items)
    

    将确保将项目数组返回给调用函数。

    接下来,要从 Hashmap 中一个一个地获取值并将它们加载到 CustomOutput 中,这就是我所做的:

    let resp: std::option::Option<Vec<HashMap<std::string::String, AttributeValue>>> = query_user(&client, &e.user_id).await?;
    

    获得响应后,如果需要,我可以深入研究第一个元素:

    x[0]
    .get("user_name")
    .unwrap()
    .as_s()
    .unwrap()
    .to_string()
    

    对于数字类型,可能类似于“battery_voltage”:

     x[0]
    .get("battery_voltage")
    .unwrap()
    .as_n()
    .unwrap()
    .to_string()
    .parse::<f32>()
    .unwrap(),
    

    最后,使用匹配块来确定数据的 Some 或 None:

    match _val {
            Some(x) => {
                // pattern
                if x.len() > 0 {
                    return Ok(json!(CustomOutput {
                        user_name: x[0].get("user_name").unwrap().as_s().unwrap().to_string(),
                        user_email: x[0].get("user_email").unwrap().as_s().unwrap().to_string(),
                    }));
                } else {
                    return Ok(json!({
                        "code": "404".to_string(),
                        "message": "Not found.".to_string(),
                    }));
                }
            }
            None => {
                // other pattern
                println!("Got nothing");
                return Ok(json!({
                    "code": "404".to_string(),
                    "message": "Not found.".to_string(),
                }));
            }
    

    希望这可以帮助别人!

    【讨论】:

      猜你喜欢
      • 2023-03-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-22
      • 2020-07-27
      • 1970-01-01
      • 2013-01-16
      相关资源
      最近更新 更多