Diesel: The trait bound `chrono::NaiveDateTime: diesel::Expression` is not satisfied

Created on 26 Jun 2017  ·  22Comments  ·  Source: diesel-rs/diesel

  • Which versions of Rust and Diesel are you using?
    Rust 1.18.0, Diesel 0.13.0.

  • Which feature flags are you using?

diesel = { version = "0.13", features = ["postgres", "chrono"] }
diesel_codegen = { version = "0.13", features = ["postgres"] }
chrono = { version = "0.4", features = ["serde"] }
serde = "1.0"
serde_derive = "1.0"
serde_json = "1.0"
  • What are you trying to accomplish?

Trying to upgrade from Diesel 0.11, Serde 0.9 and Chrono 0.3 to the above versions.

  • What is the full error you are seeing?

I'm seeing the following for each AsChangeset that uses chrono::NaiveDateTime:

error[E0277]: the trait bound `chrono::NaiveDateTime: diesel::Expression` is not satisfied
  --> src/models/emails.rs:37:10
   |
37 | #[derive(AsChangeset, Clone, Debug)]
   |          ^^^^^^^^^^^ the trait `diesel::Expression` is not implemented for `chrono::NaiveDateTime`
   |
   = note: required because of the requirements on the impl of `diesel::Expression` for `&chrono::NaiveDateTime`
   = note: required because of the requirements on the impl of `diesel::expression::AsExpression<diesel::types::Timestamp>` for `&chrono::NaiveDateTime`
   = note: this error originates in a macro outside of the current crate
  • How can we reproduce this?

I think this should be reproducible with the above versions of Chrono and Diesel by having a table that has a column of type chrono::NaiveDateTime, then having an AsChangeset struct that tries to update said NaiveDateTime column.

I'm using NaiveDateTime in Rust for Postgres' TIMESTAMP:

updated_at TIMESTAMP NOT NULL default now()

I've been going round in circles with this, but if it isn't actually a Diesel issue then I apologise in advance. Thanks for all the work on Diesel, it's excellent! :)

Most helpful comment

Does cargo tree give you two diesel versions? I'd assume so, because r2d2-diesel uses the latest diesel, not its master branch.

Maybe a better way to get this going is to _not_ specify diesel master, but 0.13.0 and adding

[replace]
"diesel:0.13.0" = { git = "https://github.com/diesel-rs/diesel" }

This replace every occurrence of diesel 0.13 in your dependency graph. (You might need to add the same lines for tje other diesel-* crates.)

All 22 comments

_Very_ nice issue description! (We should steal this and make it a template!)

I think your problem stems from chrono recently yanking its 0.3.1 version and releasing 0.4 with serde 1.0 support instead (this was a breaking change in 0.3.1!). Diesel 0.13.0 _does not_ support chrono 0.4. Which means two versions of chrono will be built, and they are not compatible to each other.

Can you try using diesel master instead?

diesel = { git = "https://github.com/diesel-rs/diesel", features = ["postgres", "chrono"] }

I've been going round in circles with this, but if it isn't actually a Diesel issue then I apologise in advance. Thanks for all the work on Diesel, it's excellent! :)

Thanks :) If it turns out this is a problem with two chrono versions, you can use cargo-tree to see this more easily.

Diesel 0.13.0 does not support chrono 0.4

Ah, that's probably what the problem is then! I saw this line and assumed it did.

Can you try using diesel master instead?

I wasn't expecting such a quick reply, I'll try it out as soon as I'm back at my work machine and let you know.

Very nice issue description! (We should steal this and make it a template!)

Thanks! I can't take credit for it though, I just filled in the details you ask for :)

Thanks! I can't take credit for it though, I just filled in the details you ask for :)

lol 😅

Right. So Diesel's master gets me past the original issue but I now have a different "this error originates in a macro outside of the current crate" error:

error[E0277]: the trait bound `diesel::pg::PgConnection: diesel::connection::Connection` is not satisfied
  --> src/database.rs:6:1
   |
6  | / lazy_static! {
7  | |     static ref CONNECTION: r2d2::Pool<ConnectionManager<PgConnection>> = {
8  | |         let config = r2d2::Config::default();
9  | |         let database_url = env::var("DATABASE_URL").expect("DATABASE_URL must be set");
...  |
12 | |     };
13 | | }
   | |_^ the trait `diesel::connection::Connection` is not implemented for `diesel::pg::PgConnection`
   |
   = note: required because of the requirements on the impl of `r2d2::ManageConnection` for `r2d2_diesel::ConnectionManager<diesel::pg::PgConnection>`
   = note: required by `r2d2::Pool`
   = note: this error originates in a macro outside of the current crate

Things I've tried:

  • Getting diesel_codegen from master too
  • Getting r2d2-diesel from master (though I wasn't expecting that to change anything since there hasn't been a commit to it since the last release)
  • Made sure I'm using the latest versions of r2d2 and r2d2-diesel.

database.rs:

use diesel::pg::PgConnection;
use r2d2;
use r2d2_diesel::ConnectionManager;
use std::env;

lazy_static! {
    static ref CONNECTION: r2d2::Pool<ConnectionManager<PgConnection>> = {
        let config = r2d2::Config::default();
        let database_url = env::var("DATABASE_URL").expect("DATABASE_URL must be set");
        let manager = ConnectionManager::<PgConnection>::new(database_url);
        r2d2::Pool::new(config, manager).expect("Failed to create pool.")
    };
}

pub fn connection() -> r2d2::Pool<ConnectionManager<PgConnection>> {
    CONNECTION.clone()
}

Feel free to close this when it gets too off topic from the original issue / becomes too specific to just how I'm using it.

Does cargo tree give you two diesel versions? I'd assume so, because r2d2-diesel uses the latest diesel, not its master branch.

Maybe a better way to get this going is to _not_ specify diesel master, but 0.13.0 and adding

[replace]
"diesel:0.13.0" = { git = "https://github.com/diesel-rs/diesel" }

This replace every occurrence of diesel 0.13 in your dependency graph. (You might need to add the same lines for tje other diesel-* crates.)

@killercup You're a gentleman and a scholar! Thanks so much for taking the time to help!


For anyone else who finds themselves here:

Add Diesel and co. as you would usually:

diesel = { version = "0.13.0", features = ["postgres", "chrono"] }
diesel_codegen = { version = "0.13.0", features = ["postgres"] }
r2d2 = "0.7"
r2d2-diesel = "0.13.0"

As @killercup said, replace the version of Diesel you're using like so:

[replace]
"diesel:0.13.0" = { git = "https://github.com/diesel-rs/diesel" }

Run cargo update to make sure r2d2-diesel is using the latest version of Diesel it can.

Build.


Thanks again @killercup 😄

Thank you! I'm glad this works for you. With the next release of Diesel, 0.14, you should only need to increment the diesel and r2d2 version, remove the [replace], and it should all just work™ :)

Just confirming that Diesel 0.14 does indeed resolve the above issues. Good work folks 👍

Thanks for confirming. :heart:

@sgrif Actually, I use 0.14 and 0.14.1 now and I have these errors:

error[E0277]: the trait bound `chrono::NaiveDateTime: phone::_IMPL_DESERIALIZE_FOR_PhoneInfo::_serde::Serialize` is not satisfied
 --> src/models.rs:9:88
  |
9 | #[derive(Debug, Clone, Queryable, Identifiable, Insertable, Associations, AsChangeset, Serialize, Deserialize)]
  |                                                                                        ^^^^^^^^^ the trait `phone::_IMPL_DESERIALIZE_FOR_PhoneInfo::_serde::Serialize` is not implemented for `chrono::NaiveDateTime`
  |
  = note: required by `phone::_IMPL_DESERIALIZE_FOR_PhoneInfo::_serde::ser::SerializeStruct::serialize_field`

error[E0277]: the trait bound `chrono::NaiveDateTime: phone::_IMPL_DESERIALIZE_FOR_PhoneInfo::_serde::Deserialize` is not satisfied
 --> src/models.rs:9:99
  |
9 | #[derive(Debug, Clone, Queryable, Identifiable, Insertable, Associations, AsChangeset, Serialize, Deserialize)]
  |                                                                                                   ^^^^^^^^^^^ the trait `phone::_IMPL_DESERIALIZE_FOR_PhoneInfo::_serde::Deserialize` is not implemented for `chrono::NaiveDateTime`
  |
  = note: required by `phone::_IMPL_DESERIALIZE_FOR_PhoneInfo::_serde::de::SeqVisitor::visit`

error[E0277]: the trait bound `chrono::NaiveDateTime: phone::_IMPL_DESERIALIZE_FOR_PhoneInfo::_serde::Deserialize` is not satisfied
 --> src/models.rs:9:99
  |
9 | #[derive(Debug, Clone, Queryable, Identifiable, Insertable, Associations, AsChangeset, Serialize, Deserialize)]
  |                                                                                                   ^^^^^^^^^^^ the trait `phone::_IMPL_DESERIALIZE_FOR_PhoneInfo::_serde::Deserialize` is not implemented for `chrono::NaiveDateTime`
  |
  = note: required by `phone::_IMPL_DESERIALIZE_FOR_PhoneInfo::_serde::de::MapVisitor::visit_value`

error: aborting due to 3 previous errors

error: Could not compile `omp-mdm-server`.

To learn more, run the command again with --verbose.
#[derive(Debug, Clone, Queryable, Identifiable, Insertable, Associations, AsChangeset, Serialize, Deserialize)]
#[table_name = "phones"]
#[primary_key(imei)]
#[belongs_to(User)]
pub struct Phone {
    pub imei: i64,
    pub model: String,
    pub vendor: String,
    pub manufacturer: String,
    pub last_sync: NaiveDateTime, // In UTC
    pub user_id: i32,
}
[dependencies]
rocket = "0.2.8"
rocket_codegen = "0.2.8"
rocket_contrib = "0.2.8"
serde = "0.9"
serde_derive = "0.9"
serde_json = "0.9"
r2d2 = "0.7.2"
r2d2-diesel = "0.14"
chrono = { version = "0.4", features = ["serde"] }

[dependencies.diesel]
version = "0.14"
default-features = false
features = ["sqlite", "chrono"]

[dependencies.diesel_codegen]
version = "0.14"
default-features = false
features = ["sqlite"]

@vityafx these look like serde issues—most likely because you are using serde 0.9 and chrono requires 1.0.

@killercup oh well, yes, totally forgot about that but I did knew that! :-D Just rocket uses old serde, this is the problem, I guess, but I can't change it :( Thanks.

Rocket 0.3 will include it: https://github.com/SergioBenitez/Rocket/issues/273#issuecomment-301339550

Maybe you can use rocket's master branch until then?

@killercup a very good notice, I have just found this information too (about it's master branch), but thanks for such a nice help here anyway!

I have read this and I still do not understand the fix.
I am tried both diesel 0.16.0 and master c5fa99574673e09e6e5029cda517802a82f66933

I have a postgress table with a TIMESTAMP column.

error[E0277]: the trait bound models::chrono::NaiveDateTime: diesel::types::FromSqlRow<diesel::types::Nullable<diesel::types::Timestamp>, diesel::pg::Pg> is not satisfied
--> src/main.rs:98:10
|
98 | .get_result(conn)
| ^^^^^^^^^^ the trait diesel::types::FromSqlRow<diesel::types::Nullable<diesel::types::Timestamp>, diesel::pg::Pg> is not implemented for models::chrono::NaiveDateTime
|
= help: the following implementations were found:
>
>
= note: required because of the requirements on the impl of diesel::types::FromSqlRow<(diesel::types::Integer, diesel::types::Nullable<diesel::types::Timestamp>, diesel::types::Text), diesel::pg::Pg> for (i32, models::chrono::NaiveDateTime, std::string::String)
= note: required because of the requirements on the impl of diesel::Queryable<(diesel::types::Integer, diesel::types::Nullable<diesel::types::Timestamp>, diesel::types::Text), diesel::pg::Pg> for models::Tst1
= note: required because of the requirements on the impl of diesel::LoadQuery<diesel::PgConnection, models::Tst1> for diesel::query_builder::insert_statement::InsertStatement<schema::__diesel_infer_schema::infer_tst1::tst1::table, (diesel::insertable::ColumnInsertValue<schema::__diesel_infer_schema::infer_tst1::tst1::columns::methd, diesel::expression::bound::Bound<diesel::types::Text, &std::string::String>>,)>

error: aborting due to previous error

@greenpdx Your issue is slightly different than that one described here. You are trying to load a nullable sql type (Nullable<Timestamp>) into a not nullable rust type (NaiveDateTime). Diesel does not support such mappings to prevent errors. Instead try to change the rust type into Option<NaiveDateTime>.

I know It's a closed issue but I encountered another similiar error: *const str: diesel::deserialize::FromSql<diesel::sql_types::Timestamp, diesel::pg::Pg, anyone knows how to fix it?

@GopherJ That error message indicates that you trying to load a Timestamp into a string which is not supported. You need to enable the chrono feature and use chrono::NaiveDateTime for this.

I get this issue still, using chrono etc.

use super::schema::trades;
use chrono;

[derive(Queryable,Debug)]

pub struct Trade {
pub id: i32,
pub cusip: Option,
pub sedol: Option,
pub isin: Option,
pub ticker: Option,
pub trade_date: chrono::NaiveDateTime,
pub published: bool,
}

[derive(Insertable,Debug)]

[table_name = "trades"]

pub struct NewTrade<'a> {
pub cusip: &'a str,
pub sedol: &'a str,
pub isin: &'a str,
pub ticker: &'a str,
pub trade_date: chrono::NaiveDateTime,

}

error[E0277]: the trait bound chrono::NaiveDateTime: diesel::Expression is not satisfied
--> src/models.rs:32:10
|
32 | #[derive(Insertable,Debug)]
| ^^^^^^^^^^ the trait diesel::Expression is not implemented for chrono::NaiveDateTime
|
= note: required because of the requirements on the impl of diesel::expression::AsExpression<diesel::sql_types::Timestamp> for chrono::NaiveDateTime

error[E0277]: the trait bound chrono::NaiveDateTime: diesel::Expression is not satisfied
--> src/models.rs:32:10
|
32 | #[derive(Insertable,Debug)]
| ^^^^^^^^^^ the trait diesel::Expression is not implemented for chrono::NaiveDateTime
|
= note: required because of the requirements on the impl of diesel::Expression for &chrono::NaiveDateTime
= note: required because of the requirements on the impl of diesel::expression::AsExpression<diesel::sql_types::Timestamp> for &chrono::NaiveDateTime

error[E0277]: the trait bound chrono::NaiveDateTime: diesel::Expression is not satisfied
--> src/models.rs:32:10
|
32 | #[derive(Insertable,Debug)]
| ^^^^^^^^^^ the trait diesel::Expression is not implemented for chrono::NaiveDateTime
|
= note: required because of the requirements on the impl of diesel::Expression for &'insert chrono::NaiveDateTime
= note: required because of the requirements on the impl of diesel::expression::AsExpression<diesel::sql_types::Timestamp> for &'insert chrono::NaiveDateTime

error: aborting due to 3 previous errors

@dosterthebernese Our issue tracker is used to track bugs and feature request. For asking questions please use our gitter channel

Was this page helpful?
0 / 5 - 0 ratings

Related issues

killercup picture killercup  ·  4Comments

ghost picture ghost  ·  3Comments

killercup picture killercup  ·  3Comments

raintears picture raintears  ·  4Comments

Fuckoffee picture Fuckoffee  ·  3Comments