Search code examples
rustrust-sqlx

Convert PgRow value of unknown type to a String


I'm trying to "pretty-print" the result of a query. I don't know the query beforehand, so I can't manually convert. My idea was to iterate over the column information for the PgRow, and then for each column get the value.

This is the code I have currently:

fn row_to_json(row: PgRow) -> HashMap<String, String> {
    let mut result = HashMap::new();
    for col in row.columns() {
        let name = col.name();
        result.insert(name.to_string(), row.get(name));
    }

    result
}

However, this panics because row.get() doesn't know how to convert just any type into a string (even an integer). I also tried serde_json::Value but that didn't work.

How should I go about doing this? Is there a way to represent any SQL type in rust that can be converted to a string, or is there a better way to format a row?


Solution

  • After some digging (and help from the discord server), I solved this. The problem is that sqlx::query returns the data encoded in binary, which apparently isn't easy to just convert to a readable string.

    If you call the .fetch_* method directly on an Executor (e.g. your pool) it will return the result as text. Combining this with the fixed code, I'm able to get a reasonable output.

    fn row_to_json(row: PgRow) -> HashMap<String, String> {
        let mut result = HashMap::new();
        for col in row.columns() {
            let value = row.try_get_raw(col.ordinal()).unwrap();
            let value = match value.is_null() {
                true => "NULL".to_string(),
                false => value.as_str().unwrap().to_string(),
            };
            result.insert(
                col.name().to_string(),
                value,
            );
        }
    
        result
    }