In rust, mysql database is connected to mysql database. How can the query result restore the original type data

I used rust's mysql library to connect to the mysql database, and the result of the query was that every data item was a character type

fn get_row<T: DeserializeOwned + Default>(r: Row) -> T {
        let mut json_obj = json!({});
        for col in r.columns_ref() {
            let col_key = col.name_str().to_string();
            let col_val = if let Value::Bytes(v) = &r[col.name_str().as_ref()] {
                std::str::from_utf8(v).unwrap()
            } else {
                ""
            };

            println!("------{}------{:#?}-----", col_key, col.column_type());

            json_obj[col_key] = col_val.into();
        }
        let res_str = serde_json::to_string_pretty(&json_obj).unwrap();
        let res: T = serde_json::from_str(&res_str).unwrap();
        res
    }

fn info<T>(conn: PooledConn) -> Result<T, std::io::Error> 
where
    T: DeserializeOwned + Default,
{
        let sql = format!("select * from company");
        let result: Option<Row> = conn.query_first(sql).expect("Data query error");

        if let Some(row) = result {
            let res: T = get_row(row);
            return Ok(res);
        }

        Ok(T::default())
}

// This is the structure passed in by calling the info method
#[derive(Deserialize, Default, Debug)]
struct Company {
    id: String,
    name: String,
    status: u32,
    err_info: String,
    account_id: String,
    create_at: String,
    update_at: String,
}

The data obtained by calling the info method is as follows, as if each data is a string, through the printing type, it should be the corresponding data of different types, how to restore the original data, ask for help

Company {
    id: "2017612633062042215",
    name: "Yangyang",
    status: "100",
    err_info: "",
    account_id: "0",
    create_at: "1710993521",
    update_at: "1711000831",
}
------id------MYSQL_TYPE_LONGLONG-----
------name------MYSQL_TYPE_VAR_STRING-----
------status------MYSQL_TYPE_SHORT-----
------err_info------MYSQL_TYPE_VAR_STRING-----
------account_id------MYSQL_TYPE_LONGLONG-----
------create_at------MYSQL_TYPE_LONGLONG-----
------update_at------MYSQL_TYPE_LONGLONG-----

The following is the data table structure
20240619143439

The raw value of bigints are stored in Value::Bytes variants. Hence why your parsing treats them simply as utf-8 strings. You really shouldn't implement parsing the mysql data to and from your types by hand. Please refer to the docs of mysql_common on how to implement parsing more efficiently (i.e. by deriving FromRow).

3 Likes

Specific guidance, the document read for a long time also do not know how to get,

You'd write code like:

use mysql_common::prelude::FromRow;

#[derive(FromRow)]
#[mysql(table_name = "company", crate_name = "mysql_common")]
struct Company {
    id: String,
    name: String,
    status: u32,
    err_info: String,
    account_id: String,
    create_at: String,
    update_at: String,
}

fn get_company_row(r: Row) -> Company {
    Company::from_row(r)
}

The crate then takes care of converting everything in the Row into your data structure as defined, and if you change the types in Company (using the list of supported types as a guide, or the FromValue derive for custom types), you'll get different outcomes.

1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.