问题:当编译时字段类型未知时,如何使用 tokio-postgres 枚举列?

我想要一个将 SQL 查询结果转换为 JSON 的通用函数。我想手动构建一个 JSON 字符串(或使用外部库)。为此,我需要能够动态地枚举一行中的列。

let rows = client
   .query("select * from ExampleTable;")
   .await?;

// This is how you read a string if you know the first column is a string type.
let thisValue: &str = rows[0].get(0);

动态类型可以使用 Rust,但不能使用 tokio-postgres 库 API。

tokio-postgres的row.get功能设计为需要根据源码进行泛型推理

如果没有正确的 API,我如何枚举行和列?

解答

您需要枚举行和列,这样做您可以在枚举时获取列引用,并从中获取 postgresql 类型。使用类型信息,可以有条件逻辑来为两者选择不同的子函数: i) 获取强类型变量;并且,ii) 转换为 JSON 值。

for (rowIndex, row) in rows.iter().enumerate() {
    for (colIndex, column) in row.columns().iter().enumerate() {
        let colType: string = col.type_().to_string();
        
        if colType == "int4" { //i32
            let value: i32 = row.get(colIndex);
            return value.to_string();
        }
        else if colType == "text" {
            let value: &str = row.get(colIndex);
            return value; //TODO: escape characters
        }
        //TODO: more type support
        else {
            //TODO: raise error
        }
    }
}

给 tokio-postgres 代码维护者的额外提示

理想情况下,tokio-postgres 将包含一个返回dyn any类型的直接 API。 row.rs 的内部已经使用数据库列类型信息来确认提供的泛型类型是否有效。理想情况下,新的 API 使用将通过改进的 FromSQL API 直接使用内部列信息,但存在更简单的中间立场:-

row.rs 中有一个额外的函数层可能会使用此答案中使用的相同列类型条件逻辑,然后利用现有的get函数。如果像我这样的用户需要处理这种条件逻辑,当由 tokio-postgresql 处理新类型时,我也需要维护这种代码,因此,这种逻辑应该包含在库中,这样功能可以更好保持。

Logo

PostgreSQL社区为您提供最前沿的新闻资讯和知识内容

更多推荐