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()将其转换为字符串后,以怪异的格式。 格式如下:
{
"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;
}