今天我一直在关注Rust's Diesel ORMthis walk-through,但我没法得到Timestamp.

Cargo.toml

[dependencies]
diesel = { version = "0.6.2", features = ["chrono"] }
diesel_codegen = { version = "0.6.2", default-features = false, features = ["nightly", "postgres"] }
dotenv = "0.8.0"
dotenv_macros = "0.8.0"

models.rs

#[derive(Queryable)]

pub struct Author {
    pub id: i32,
    pub first_name: String,
    pub last_name: String,
    pub email: String
}

pub struct Post {
    pub id: i32,
    pub author: Author,
    pub title: String,
    pub body: String,
    pub published: bool,
    pub created: Timestamp,
    pub updated: Timestamp
}

(我读到有diesel::types::Timestamp种)

lib.rs

#![feature(custom_derive, custom_attribute, plugin)]
#![plugin(diesel_codegen, dotenv_macros)]

#[macro_use]
extern crate diesel;
extern crate dotenv;

pub mod schema;
pub mod models;

use diesel::prelude::*;
use diesel::types::Timestamp;
use diesel::pg::PgConnection;
use dotenv::dotenv;
use std::env;

pub fn establish_connection() -> PgConnection {
    dotenv().ok();

    let database_url = env::var("DATABASE_URL").
        expect("DATABASE_URL must be set");
    PgConnection::establish(&database_url).
        expect(&format!("Error connecting to {}", database_url))
}

但当我try 使用它时,我会遇到以下错误:

<diesel macros>:5:1: 5:71 note: in this expansion of table_body! (defined in <diesel macros>)
src/schema.rs:1:1: 1:40 note: in this expansion of table! (defined in <diesel macros>)
src/schema.rs:1:1: 1:40 note: in this expansion of infer_schema! (defined in src/lib.rs)
src/lib.rs:1:1: 1:1 help: run `rustc --explain E0412` to see a detailed explanation
src/lib.rs:1:1: 1:1 help: no candidates by the name of `Timestamptz` found in your project; maybe you misspelled the name or forgot to import an external crate?
src/lib.rs:1:1: 1:1 error: type name `Timestamptz` is undefined or not in scope [E0412]
src/lib.rs:1 #![feature(custom_derive, custom_attribute, plugin)]

...

<diesel macros>:38:1: 38:47 note: in this expansion of column! (defined in <diesel macros>)
<diesel macros>:5:1: 5:71 note: in this expansion of table_body! (defined in <diesel macros>)
src/schema.rs:1:1: 1:40 note: in this expansion of table! (defined in <diesel macros>)
src/schema.rs:1:1: 1:40 note: in this expansion of infer_schema! (defined in src/lib.rs)
src/lib.rs:1:1: 1:1 help: run `rustc --explain E0412` to see a detailed explanation
src/lib.rs:1:1: 1:1 help: no candidates by the name of `Timestamptz` found in your project; maybe you misspelled the name or forgot to import an external crate?
src/models.rs:16:18: 16:27 error: type name `Timestamp` is undefined or not in scope [E0412]
src/models.rs:16     pub created: Timestamp,
                              ^~~~~~~~~
src/models.rs:16:18: 16:27 help: run `rustc --explain E0412` to see a detailed explanation
src/models.rs:16:18: 16:27 help: you can import it into scope: `use diesel::types::Timestamp;`.
src/models.rs:17:18: 17:27 error: type name `Timestamp` is undefined or not in scope [E0412]
src/models.rs:17     pub updated: Timestamp
                              ^~~~~~~~~

看起来像是第一个错误,Timestamptzinfer_schema不知道如何解释表中已经存在的Postgresql类型的结果.至于第二个,我想如果显式导入Timestamp类型,我可以用它创建一个Post struct .

有没有什么明显的事情表明我做错了?

顺便说一句,我对Rust 和柴油机使用了相当多的代码生成,所以很容易丢失,但我认为这应该是一个简单的事情来完成.


Edit:

我用timestamp with time zone创建了这个表,它看起来像may not be supported yet:

CREATE TABLE post (
    ...
    created timestamp with time zone NOT NULL,
    updated timestamp with time zone
)

Edit 2:

我将models.rs改为如下所示,并消除了Timestamp未定义的错误.我还意识到,我需要在每个 struct 之上派生#[derive(Queryable)]个.下面的编译很好,但之前的Timestamptz错误仍然存在:

use diesel::types::Timestamp;

#[derive(Queryable)]
pub struct Author {
    pub id: i32,
    pub first_name: String,
    pub last_name: String,
    pub email: String
}

#[derive(Queryable)]
pub struct Post {
    pub id: i32,
    pub author: Author,
    pub title: String,
    pub body: String,
    pub published: bool,
    pub created: Timestamp,
    pub updated: Timestamp
}

推荐答案

diesel::sql_types中的所有类型都是表示模式的各种SQL数据类型的标记.它们不应该用在你自己的 struct 中.您需要的是一个实现diesel::deserialize::FromSql<diesel::sql_types::Timestamp, diesel::pg::Pg>的类型(文档:FromSqlTimestampPg).有两种类型可以实现这种特性.

第一个是std::time::SystemTime,它不需要额外的依赖项,但没有太多的功能.

第二个是chrono::NaiveDateTime.这可能就是你想要的类型.为了使用它,您需要在依赖项中添加chrono,并更改Cargo中的柴油线.toml将包含chrono功能,因此看起来像diesel = { version = "0.7.0", features = ["postgres", "chrono"] }

(从技术上讲,还有第三种类型,即diesel::data_types::PgTimestamp,但这几乎肯定不是您想要的,因为该 struct 只是数据库中时间戳的文字表示,所以其他类型不必担心原始字节)

Postgresql相关问答推荐

如何在gorm中创建一个可读但不可写的字段

PostgreSQL按描述请求

PostgreSQL\d命令:有办法只 Select 一列吗?

如何使用 go-pg 包删除所有记录

如何将特定值排序为最后,其余记录按 id DESC 排序?

如何创建一个触发器来传播对主键表的更新?

这个 Supbase 查询在 SQL ( Postgresql ) 中的类似功能是什么

在 jOOQ 中 Select 相同的命名列

sql:转换参数 $1 类型:不支持的类型 []int,in 的一部分

postgresql中的外键可以被触发器违反

如何从 WSL 连接到 windows postgres 数据库

在 PostgreSQL 中将时间转换为秒

PostgreSQL:如何安装 plpythonu 扩展

仅在存在时重命名列

在 Postgres 中显示关系、序列和函数的默认访问权限

有没有办法确保 WHERE 子句在 DISTINCT 之后发生?

GRANT SELECT 特权使用一个语句对所有序列

升级到 Yosemite 10.10 后无法连接到 postgresql 数据库

在 OS X 上使用 Postgres.app 时如何将 psql 放在路径上?

使用python将数据从csv复制到postgresql