首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用生锈语言从dynamoDB查询特定的属性集?

如何使用生锈语言从dynamoDB查询特定的属性集?
EN

Stack Overflow用户
提问于 2022-06-16 09:59:12
回答 1查看 175关注 0票数 1

我是生疏的,这个问题可能会变得很愚蠢。我正在尝试开发一个lambda,它读取dynamoDB给出的密钥中的单个条目。返回的项需要作为结果共享给调用lambda。

我希望响应在JSON中。

以下是我所拥有的:

输入结构

代码语言:javascript
复制
#[derive(Deserialize, Clone)]
struct CustomEvent {
    #[serde(rename = "user_id")]
    user_id: String,
}

输出结构

代码语言:javascript
复制
#[derive(Serialize, Clone)]
struct CustomOutput {
    user_name: String,
    user_email: String,
}

主fn

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

要查询的逻辑

代码语言:javascript
复制
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

代码语言:javascript
复制
[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结构返回到

代码语言:javascript
复制
Ok(CustomOutput {
        // user_name: resp[0].user_name,
        // user_email: resp[0].user_email,
    })

在get_user_details中阻塞。任何帮助或推荐信都会有很大帮助。谢谢。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-06-20 11:29:33

经过几次尝试,我学到了以下内容:可以使用match关键字来代替在变量中收集结果。我做了这个:

代码语言:javascript
复制
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),
    }

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

所以,这一行:

代码语言:javascript
复制
Ok(resp) => Ok(resp.items)

将确保items数组返回到调用函数。

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

代码语言:javascript
复制
let resp: std::option::Option<Vec<HashMap<std::string::String, AttributeValue>>> = query_user(&client, &e.user_id).await?;

一旦我得到了resp,如果需要这样的话,我可以挖掘到第一个元素:

代码语言:javascript
复制
x[0]
.get("user_name")
.unwrap()
.as_s()
.unwrap()
.to_string()

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

代码语言:javascript
复制
 x[0]
.get("battery_voltage")
.unwrap()
.as_n()
.unwrap()
.to_string()
.parse::<f32>()
.unwrap(),

最后,使用匹配块来确定数据的部分或无值:

代码语言:javascript
复制
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(),
            }));
        }

希望这能帮到别人!

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72644005

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档