【问题标题】:Is it possible to deserialize tokio_postgres rows without Struct?是否可以在没有 Struct 的情况下反序列化 tokio_postgres 行?
【发布时间】:2021-11-25 00:10:05
【问题描述】:

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

我做了谷歌,发现所有可用包中使用的所有示例都需要首先将每行数据解包到一个结构中,这是我试图绕过的东西。我希望能够运行动态 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 的情况下执行此操作,请有人分享您的代码 sn-p。 谢谢

【问题讨论】:

    标签: postgresql rust actix-web tokio


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

      解决方案 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 使用 quote 板条箱作为a proc-macro to make mapping from postgresql tables to structs,那么为什么我们不使用quote 或类似的东西来构建另一个板条箱,甚至只是在我们的项目中使用它?

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

      【讨论】:

      • 正如它所写的,听起来你有同样的问题,但还没有答案,但对问题可能出在哪里有些怀疑,尽管没有机会评估那些.如果是这样,最好等到有机会后再发布更全面的答案。
      猜你喜欢
      • 2014-12-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-09-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多