You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

启用rust-postgres特性获取PostgreSQL JSON结果时遇列不存在错误

问题原因

你遇到的column "s" does not exist错误,根源是rust-postgres不支持%s这种C风格的参数占位符——它遵循PostgreSQL原生规则,使用$1、$2这类位置标记绑定参数。你的SQL里写了WHERE table_schema=%s,执行时PostgreSQL没识别出这是占位符,反而把%s当成了列名s,因此抛出找不到列的错误。

解决方案

把查询语句中的%s替换为PostgreSQL原生的$1占位符,同时结合你启用的with-serde_json-1特性,可以直接将JSON结果解析为serde_json::Value进行遍历操作。修正后的完整代码如下:

extern crate postgres;
extern crate serde_json;

use postgres::{Client, NoTls};
use serde_json::Value;

fn main() {
    // 替换为实际数据库连接信息
    let db_url = "postgresql://postgres:mypass@localhost/users";

    // 连接数据库
    let mut client = Client::connect(db_url, NoTls).expect("连接数据库失败");
    let schema = "public";

    // 修正占位符为PostgreSQL原生的$1
    let query = r#"
        select row_to_json(Tb) as tbls from(
        SELECT T."table_name", (select json_agg(col) from (
        SELECT "column_name", udt_name, is_nullable, data_type, column_default FROM
        information_schema.columns WHERE table_name = T."table_name" AND column_default NOT LIKE 'nextval%%'
        ) col ) as cols,

        (select json_agg(colx) from (
        SELECT "column_name", udt_name, is_nullable, data_type, column_default FROM
        information_schema.columns WHERE table_name = T."table_name"
        ) colx ) as identifiable_columns,

        (select json_agg(colr) from (
        SELECT
            tc.table_name,
            kcu.column_name,
            ccu.table_name AS foreign_table_name,
            ccu.column_name AS foreign_column_name
        FROM
            information_schema.table_constraints AS tc
            JOIN information_schema.key_column_usage AS kcu
              ON tc.constraint_name = kcu.constraint_name
              AND tc.table_schema = kcu.table_schema
            JOIN information_schema.constraint_column_usage AS ccu
              ON ccu.constraint_name = tc.constraint_name
              AND ccu.table_schema = tc.table_schema
        WHERE tc.constraint_type = 'FOREIGN KEY' AND tc.table_name=T."table_name"
        ) colr ) as relates
        FROM information_schema.tables as T
        WHERE table_schema=$1) Tb;
    "#;

    // 执行查询并解析JSON结果
    let rows = client.query(query, &[&schema]).expect("执行查询失败");
    
    // 遍历结果并处理JSON
    for row in rows {
        let tbl_json: Value = row.get("tbls");
        println!("表结构JSON: {:#?}", tbl_json);
        
        // 示例:提取表名和列信息
        if let Some(table_name) = tbl_json.get("table_name").and_then(Value::as_str) {
            println!("表名: {}", table_name);
        }
        if let Some(cols) = tbl_json.get("cols").and_then(Value::as_array) {
            println!("列列表:");
            for col in cols {
                println!("  列名: {}", col.get("column_name").unwrap().as_str().unwrap());
            }
        }
    }
}
补充说明
  1. 占位符规则:rust-postgres严格遵循PostgreSQL的位置占位符逻辑,$n对应参数列表中的第n个元素,这里$1对应&[&schema]里的第一个参数。
  2. JSON解析:启用with-serde_json-1特性后,可直接通过row.get方法将查询结果中的JSON字段解析为serde_json::Value,方便后续遍历、提取数据。
  3. 模糊匹配写法:在Rust原始字符串(r#"..."#)中,%无需额外转义,你写的nextval%%会被PostgreSQL正确识别为nextval%的模糊匹配规则。

内容的提问来源于stack exchange,提问作者alexander

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 21:18:14