2

我正在使用rust-postgres crate 来摄取数据。这是一个成功添加行的工作示例:

    let name: &str = "hello from rust";
    let val: i32 = 123;
    let now: DateTime<Utc> = Utc::now();
    let timestamp = now.format("%Y-%m-%dT%H:%M:%S%.6f").to_string();
    client.execute(
        "INSERT INTO trades VALUES(to_timestamp($1, 'yyyy-MM-ddTHH:mm:ss.SSSUUU'),$2,$3)",
        &[&timestamp, &name, &val],
    )?;

这看起来不太好,因为我必须进行前后字符串转换,我希望能够编写类似的东西

    let name: &str = "hello from rust";
    let val: i32 = 123;
    let now: DateTime<Utc> = Utc::now();
    client.execute(
        "INSERT INTO trades VALUES($1,$2,$3)",
        &[&now, &name, &val],
    )?;

以这种方式摄取时间戳的最高效方式是什么?

编辑:

这是上面第二个示例返回的错误

Error: Error { kind: ToSql(0), cause: Some(WrongType { postgres: Timestamp, rust: "chrono::datetime::DateTime<chrono::offset::utc::Utc>" }) }

我的cargo.toml样子是这样的(它为 rust postgres crate 启用了计时功能):

[dependencies]
chrono = "0.4.19"
postgres={version="0.19.0", features=["with-serde_json-1", "with-bit-vec-0_6", "with-chrono-0_4"]}
4

2 回答 2

1

我认为问题在于你的 postgres 模式和你的 Rust 类型不匹配:错误似乎说你的 postgres 类型是timestamp,而你的 rust 类型是DateTime<Utc>.

如果检查转换表,则DateTime<Utc>转换为TIMESTAMP WITH TIME ZONE. 唯一转换为的类型TIMESTAMPNaiveDateTimePrimitiveDateTime

于 2021-01-21T13:14:25.983 回答
0

根据Masklinn 的回复,我需要传递一个NaiveDateTime类型才能使其工作,完整示例naive_local如下所示:

use postgres::{Client, NoTls, Error};
use chrono::{Utc};
use std::time::SystemTime;

fn main() -> Result<(), Error> {
    let mut client = Client::connect("postgresql://admin:quest@localhost:8812/qdb", NoTls)?;

    // Basic query
    client.batch_execute("CREATE TABLE IF NOT EXISTS trades (ts TIMESTAMP, date DATE, name STRING, value INT) timestamp(ts);")?;

    // Parameterized query
    let name: &str = "rust example";
    let val: i32 = 123;
    let utc = Utc::now();
    let sys_time = SystemTime::now();
    client.execute(
        "INSERT INTO trades VALUES($1,$2,$3,$4)",
        &[&utc.naive_local(), &sys_time, &name, &val],
    )?;

    // Prepared statement
    let mut txn = client.transaction()?;
    let statement = txn.prepare("insert into trades values ($1,$2,$3,$4)")?;
    for value in 0..10 {
        let utc = Utc::now();
        let sys_time = SystemTime::now();
        txn.execute(&statement, &[&utc.naive_local(), &sys_time, &name, &value])?;
    }
    txn.commit()?;

    println!("import finished");
    Ok(())
}
于 2021-02-10T11:35:54.447 回答