这是我使用postgres
创建的代码,用于将数据插入Postgres数据库中(不幸的是,在Rust Playground上没有此crate):
使用以下Cargo.toml:
Original Answer翻译成"最初的回答"[package]
name = "suff-import"
version = "0.1.0"
authors = ["greg"]
[dependencies]
csv = "1"
postgres = "0.15"
uuid = "0.7"
File 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转换为&str
,因为Postgres应该隐式地将其转换为UUID,但是并没有起作用(出现相同的错误消息)。然后我在Postgres查询中添加了一个显式的$1::uuid
,但问题仍然存在。"最初的回答"
$1::uuid
和&stuff.stuff_id
(不转换为&str
),要么使用$1
(没有::uuid
)和&format!("{}", &stuff.stuff_id).as_str()
。现在你告诉postgres需要一个UUID对象,但实际上传递的是一个字符串... - Jmb$1::uuid
是对第一个参数的转换运算符,如果第一个参数是字符串,它将被转换为uuid
。在 Rust 部分中,用于传递查询参数的数组是&str
数组。我将遵循 @shepmaster 的指示提出更好的问题。 - greg