使用SQL Server数据库创建Rust后端

问题描述 投票:0回答:1
我一直在尝试找到一种很好的方法来创建诸如后端使用Rust之类的Express.js。除了我找不到一个很好的方法连接和查询SQL Server数据库的事实外,一切似乎都很好。 我尝试使用ACTIX和SQLX 0.6.3,该0.6.3仍然具有SQL Server支持,但是在尝试查询数据库时,我会遇到错误。

Proc宏观恐慌 消息:未实现:名称:不支持的数据类型Decimaln

我使用了此代码:

use actix_web::{web, App, HttpServer, Responder, get, middleware::Logger}; use sqlx::mssql::MssqlConnection; use sqlx::Connection; const DATABASE_URL: &str = "mssql://User:password@server/database"; #[actix_web::main] async fn main() -> std::io::Result<()> { // Create a single connection let mut connection = MssqlConnection::connect(DATABASE_URL) .await .expect("Failed to connect to the database"); // Example of using the connection let result = sqlx::query!(" SELECT * From my_table ") .fetch_all(&mut connection) .await?; // Print the result or handle it as needed println!("{:?}", result); // Start the Actix web server HttpServer::new(move || { App::new() .wrap(Logger::default()) .route("/", web::get().to(example_handler)) }) .bind("127.0.0.1:8080")? .run() .await }
我尝试了上述代码,希望有一个简单的响应,但出现了错误。 当我只给出静态响应时,我可以从端点获取数据。只有当我尝试执行SQL语句时,我才会得到上面显示的错误。

对此主题的任何帮助都将不胜感激。

因此,我花了一些时间搜索Rust Docs和Internet寻求答案,最后提出了解决方案。
use polars::prelude::*;
use connectorx::prelude::*;

    const DATABASE_URL: &str = "mssql://UserName:Password@Server:PORT/DB_NAME";


    let source_conn: SourceConn = SourceConn::try_from(DATABASE_URL).expect("failed to create connection");  
  
    //function needs to be wrapped in a blocking task so that the async runtime doesn't panic
    let destination: Arrow2Destination= tokio::task::spawn_blocking(move || {
   
      let queries:  &[CXQuery;1] = &[CXQuery::from(&db_query)]; //&db_query is an already prepared SQL Statement
      
      connectorx::get_arrow2::get_arrow2(
      &source_conn,
      None,
      queries).expect("Query failed")})
      .await
      .expect("Failed to join the blocking task");

这种方法可以获得一个arrow2destination变量。可以将其转换为数据框架,然后转换为字符串。

//convert the 'destination' variable to a DataFrame Object let df: DataFrame = destination.polars().unwrap(); //Convert DataFrame to String. This STring can then be later used to return JSON data let df_json: String = serde_json::to_string(&df).unwrap(); //this is to convert the JSON String into an easier to handle JSON format //The Stringify function is not a standard rust function //The Stringify() method logic/body can be seen below on this post let fmt_data = stringify(&df_json).await;

json字符串通过serde_json :: to_string()将其转换为字符串后,以怪异的格式。 格式如下:
rust actix-web rust-sqlx
1个回答
0
投票
{ "columns": [ { "bit_settings": "", "datatype": "Utf8", "name": "ID", "values": [ "F-1", "F-2" ] }, { "bit_settings": "", "datatype": "Utf8", "name": "Field1", "values": [ "Value 1-1", "Value 1-2" ] }, { "bit_settings": "", "datatype": "Utf8", "name": "Field2", "values": [ "Value 2-1", "Value 2-2" ] }, { "bit_settings": "", "datatype": "Int64", "name": "Field3", "values": [ 1, 2 ] } ] }

要将这种格式转换为更“经典”的JSON样式,我写了自己的“ stringify()”函数,然后在“正常”格式中创建一个新的JSON字符串。 然后,stringify()之后的格式如下:
[
    {
        "ID": "F-1",
        "Field1": "Value 1-1",
        "Field2": "Value 2-1",
        "Field3": 1
    },
    {
        "ID": "F-2",
        "Field1": "Value 1-2",
        "Field2": "Value 2-2",
        "Field3": 2
    }
]

我发现以这种格式处理数据要比Serde_json :: to_string()
返回的格式容易得多。
Stringify函数如下:

use connectorx::prelude::*; use serde_json::Value; pub async fn stringify(data: &String) -> String{ let json: Value = serde_json::from_str(&data).unwrap(); let columns = json["columns"].as_array().unwrap(); // Create an empty vector to store the transformed data let mut data: Vec<serde_json::Map<String, Value>> = Vec::new(); // Iterate over each column for i in 0..columns.len() { let column = &columns[i]; // Get the column name and values let name = column["name"].as_str().unwrap(); let values = column["values"].as_array().unwrap(); // Iterate over the values and create a new data object for each for j in 0..values.len() { // Safe casting to string let value = if let Some(value) = values[j].as_str() { value.to_string() } else { // Handle the case where the value is not a string values[j].to_string() }; // If the data object doesn't exist, create it if data.len() <= j { data.push(serde_json::Map::new()); } // Insert the value into the data object data[j].insert(name.to_string(), Value::String(value.to_string())); } } let transformed_json = serde_json::to_string(&data).unwrap(); //println!("Transformed Json: {transformed_json}"); return transformed_json; }
    

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.