错误:错误 { kind: ToSql(0), cause: Some(WrongType { postgres: Json, rust: “alloc::string::String” }) }

Error: Error { kind: ToSql(0), cause: Some(WrongType { postgres: Json, rust: "alloc::string::String" }) }

提问人:Bumin Qagan 提问时间:11/7/2023 更新时间:11/7/2023 访问量:46

问:

我试图将 json 值插入我的表中并出现错误

async fn insert_values(client: &Client, user: Report) -> Result<(), Error> {
    // Serialize the user data to JSON
    let user_json = json!({
        "username": user.username,
        "gender": {
            "val": user.gender.val,
        },
    });
     let res = serde_json::to_string(&user_json ).unwrap();
    // Execute the SQL statement to insert values
    client
        .execute("INSERT INTO users (user_report) VALUES ($1)", &[&res])
        .await?;
    Ok(())
}

喜欢这个Error: Error { kind: ToSql(0), cause: Some(WrongType { postgres: Json, rust: "alloc::string::String" }) }

这里是创建表函数

async fn create_table(client: &Client) -> Result<(), Error> {
    // Define the SQL statement to create a table if it doesn't exist
    let command = r#"
        CREATE TABLE IF NOT EXISTS users (
            id SERIAL PRIMARY KEY,
            user_report JSONB
        )"#;

    // Execute the SQL statement to create the table
    client.execute(command, &[]).await?;
    Ok(())
}

和 Cargo.toml

[dependencies]
serde = {version = "1.0.164", features=["derive"]}
serde_json = "1.0.103"
tokio-postgres = [version = "0.7.10", features= ["with-serde_json-1"]]
tokio = { version = "1", features = ["full"] }

输出错误是,代码端编译时没有任何错误,但在 posgre 本身中出现了一些此类错误Error: Error { kind: ToSql(0), cause: Some(WrongType { postgres: Json, rust: "alloc::string::String" }) }

PostgreSQL Rust-tokio tokio-postgres

评论

0赞 Yoric 11/7/2023
难道不应该使用 docs.rs/tokio-postgres/latest/tokio_postgres/types/...而不是序列化为字符串吗?
0赞 Bumin Qagan 11/7/2023
使用 tokio_postgres::types::Json; |^^^^^^^^^^^^^^^^^^^^^^^^^^^ 没有Jsontypes
0赞 Yoric 11/7/2023
有趣。这种类型似乎已经从 .调查。postgres_types
0赞 Yoric 11/7/2023
啊,它需要功能.with-serde_json-1
0赞 Bumin Qagan 11/7/2023
知道了,非常感谢

答:

3赞 pr0gramista 11/7/2023 #1

查看特征实现,我看到特征 ToSql 是针对 Value 枚举而不是 String 实现serde_json。

如果您有一个实现 Serialize 的结构,则可以使用 将其序列化为 Value。serde_json::to_value(...)

您可以跳过序列化到 String 并直接传递 Value:

async fn insert_values(client: &Client, user: Report) -> Result<(), Error> {
    // Serialize the user data to JSON
    let user_json = json!({
        "username": user.username,
        "gender": {
            "val": user.gender.val,
        },
    });
    // Execute the SQL statement to insert values
    client
        .execute("INSERT INTO users (user_report) VALUES ($1)", &[&user_json])
        .await?;
    Ok(()
}

评论

0赞 Bumin Qagan 11/7/2023
6 | .execute(“插入用户 (user_report) 值 ($1)”, &[&user_json]) |^^^^^^^^^^未实现此错误的特征ToSqlserde_json::Value
1赞 Yoric 11/7/2023
你有没有机会删除?这个解决方案对我有用。with-serde_json-1
1赞 Yoric 11/7/2023 #2

实际上,如果激活了功能标志,则看起来不是必需的。因此,我建议使用 @pr0gramista 的答案,它稍微简洁一些。Jsonwith-serde_json-1


tokio-postgres有一个隐藏在功能标志后面的 。structJsonwith-serde_json-1

use tokio_postgres::types::Json;


async fn insert_values(client: &Client, user: Report) -> Result<(), Error> {
    // Serialize the user data to JSON
    let user_json = Json(json!({ // <-- `Json` can be bound into SQL.
        "username": user.username,
        "gender": {
            "val": user.gender.val,
        },
    }));
    // Execute the SQL statement to insert values
    client
        .execute("INSERT INTO users (user_report) VALUES ($1)", &[&user_json])
        .await?;
    Ok(()
}

我正在使用以下依赖项

[dependencies]
serde = "1.0.192"
serde_json = "1.0.108"
tokio = { version = "1.33.0", features = ["full"] }
tokio-postgres = { version = "0.7.10", features = ["with-serde_json-1"] }

评论

0赞 Bumin Qagan 11/7/2023
知道了,非常感谢