0

我是 Rust 的新手,正在尝试构建一个简单的 API 服务器,该服务器连接到 Postgresql 数据库,该数据库具有运行直接 sql 查询并输出 JSON 作为结果的 API 路由。

我做了谷歌,发现所有可用包中使用的所有示例都需要首先将每行数据解包到 Struct 中,这是我试图绕过的东西。我希望能够运行动态 sql 查询并将其作为 JSON 数据输出到客户端。

我正在使用 actix-web、deadpool-postgres 和 tokio_postgres

这是我目前所拥有的 main.rs

use actix_web::{dev::ServiceRequest, web, App, HttpServer};
use deadpool_postgres::{Manager, Pool};
use tokio_postgres::{Config, NoTls};

mod handlers;

#[actix_rt::main]
async fn main() -> std::io::Result<()> {
   dotenv::dotenv().ok();
   std::env::set_var("RUST_LOG", "actix_web=debug");

   let mut cfg = Config::new();
   cfg.host("localhost");
   cfg.port(5432);
   cfg.user("postgres");
   cfg.password("postgres");
   cfg.dbname("testdb");

   let mgr = Manager::new(cfg, NoTls);
   let pool = Pool::new(mgr, 100);

   // Start http server
   HttpServer::new(move || {
       App::new()
          .data(pool.clone())
          .route("/ExecuteQuery", web::get().to(handlers::execute_query))
   })
   .bind("127.0.0.1:8081")?
   .run()
   .await
}

这是 handlers.rs

use actix_web::{web, HttpResponse, Error}; // Responder};
use deadpool_postgres::{Pool};
// use tokio_postgres::{Error};

pub async fn execute_query(db: web::Data<Pool>) -> Result<HttpResponse, Error> {
    let mut conn = db.get().await.unwrap();
    let statment = conn.prepare("Select * From People").await.unwrap();

    let rows = conn.query(&statment, &[]).await?;

    // I am trying to use do the following lines but its giving an type mismatched compile error
    // let people = serde_postgres::from_rows(&rows).unwrap();
    // let json = rustc_serialize::json::encode(people).unwrap();

    Ok(HttpResponse::Ok().json("Route called successfully"))
}

如果您能够在没有 Struct 的情况下执行此操作,有人可以分享您的代码片段吗?谢谢

4

2 回答 2

0

解决方案 A:

postgres-derive/src/fromsql.rs可能是最简单的方法,每个字段的值都来自postgres-types/src/private.rs,我们不需要基于postgres-types/src/的所有类型的准备好的结构type_gen.rs,基本使用就够了。理论上我们可以通过postgresql查询得到各种oid,即使是用户定义的结构。

解决方案 B:

SELECT some_compression_algorithm(json_agg(t), compression_level) FROM (
    your query here
) t;

问题是可能有用户定义的结构,我也很困惑......

但...

有一些有趣的东西,tokio-postgres-mapper使用quotecrate 作为a proc-macro to make mapping from postgresql tables to structs,那么为什么我们不使用quote或类似的东西来构建另一个 crate,甚至只是在我们的项目中使用它?

我会在几天内尝试更新我的答案,否则我必须回到 kotlin 和 vert.x(只是为了好玩)

于 2021-11-21T18:11:41.233 回答
0

据我所知,postgres数据库中所有查询结果的结构都不是json格式。如果需要json格式的数据,只能先获取数据,然后手动转换成json格式。目前应该be no crates 会自动帮你把数据转换成json格式,因为相比json,直接将结果解析成结构显然更容易使用

于 2020-07-15T13:57:27.913 回答