【问题标题】:Cannot convert to or from a Postgres value of type `uuid` when inserting into Postgres插入 Postgres 时无法转换为“uuid”类型的 Postgres 值或从其转换
【发布时间】:2019-03-19 16:49:50
【问题描述】:

这是我使用 postgres crate 将数据插入 Postgres 数据库的代码(不幸的是,Rust Playground 上不存在):

使用以下 Cargo.toml:

[package]
name = "suff-import"
version = "0.1.0"
authors = ["greg"]

[dependencies]
csv = "1"
postgres = "0.15"
uuid = "0.7"

文件main.rs

extern crate csv;
extern crate postgres;
extern crate uuid;

use uuid::Uuid;
use postgres::{Connection, TlsMode};
use std::error::Error;
use std::io;
use csv::StringRecord;

struct Stuff {
    stuff_id: Uuid,
    created_at: String,
    description: String,
    is_something: bool,
}

impl Stuff {
    fn from_string_record(record: StringRecord) -> Stuff {
        Stuff {
            stuff_id: Uuid::parse_str(record.get(0).unwrap()).unwrap(),
            created_at: record.get(1).unwrap().to_string(),
            description: record.get(2).unwrap().to_string(),
            is_something: record.get(3).unwrap().to_string().parse::<i32>().unwrap() == 2,
        }
    }
}

fn save_row(dbcon: &Connection, stuff: Stuff) -> Result<(), Box<Error>> {
    dbcon.execute(
        "insert into public.stuff (stuff_id, created_at, description, is_something) values ($1::uuid, $2, $3, $4)",
        &[&format!("{}", &stuff.stuff_id).as_str(), &stuff.created_at, &stuff.description, &stuff.is_something]
    )?;
    Ok(())
}


fn import() -> Result<(), Box<Error>> {
    let mut reader = csv::Reader::from_reader(io::stdin());
    let dbcon = Connection::connect("postgres://gregoire@10.129.198.251/gregoire", TlsMode::None).unwrap();

    for result in reader.records() {
        let record = result?;
        println!(".");
        save_row(&dbcon, Stuff::from_string_record(record))?;
    }

    Ok(())
}

fn main() {
    if let Err(error) = import() {
        println!("There were some errors: {}", error);
        std::process::exit(1);
    }
}

程序可以编译,但运行时退出并显示错误消息:

./target/debug/suff-import <<EOF
stuff_id,created_at,description,is_something
5252fff5-d04f-4e0f-8d3e-27da489cf40c,"2019-03-15 16:39:32","This is a description",1
EOF
.
There were some errors: type conversion error: cannot convert to or from a Postgres value of type `uuid`

我测试了使用 format! 宏将 UUID 转换为 &amp;str,因为 Postgres 应该隐式转换为 UUID,但它不起作用(相同的错误消息)。然后我在 Postgres 查询中添加了一个明确的$1::uuid,但问题仍然存在。

【问题讨论】:

  • 我想说,要么使用$1::uuid&amp;stuff.stuff_id(不转换为&amp;str),要么使用$1(不使用::uuid)和&amp;format!("{}", &amp;stuff.stuff_id).as_str()。正如你告诉 postgres 期待一个 UUID 对象,但你传递一个字符串......
  • @Jmb,$1::uuid是第一个参数的强制转换运算符,如果第一个参数是字符串,它将被强制转换为uuid。在 rust 部分,用于传递查询参数的数组是&amp;str 的数组。我将按照@shepmaster 的说明提供更好的问题。

标签: postgresql rust


【解决方案1】:

crate page 声明:

可选功能

UUID 类型

with-uuid 功能可选地提供 UUID 支持,该功能为uuidUuid 类型添加了ToSqlFromSql 实现。需要uuid 0.5 版。

您尚未指定功能,并且您使用的 uuid 版本不兼容。

Cargo.toml

[package]
name = "repro"
version = "0.1.0"
edition = "2018"

[dependencies]
postgres = { version = "0.15.2", features = ["with-uuid"] }
uuid = "0.5"

数据库设置

CREATE TABLE junk (id uuid);

代码

use postgres::{Connection, TlsMode};
use std::error::Error;
use uuid::Uuid;

fn main() -> Result<(), Box<Error>> {
    let conn = Connection::connect(
        "postgresql://shep@localhost:5432/stackoverflow",
        TlsMode::None,
    )
    .unwrap();

    let stuff_id = Uuid::default();

    conn.execute(
        "insert into public.junk (id) values ($1)",
        &[&stuff_id],
    )?;

    Ok(())
}

另见:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-02-26
    • 2012-11-20
    • 2018-05-14
    • 2016-07-19
    • 2021-06-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多