New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
elliotekj opened this Issue Jun 26, 2017 · 17 comments

Comments

Projects
None yet
6 participants
@elliotekj

elliotekj commented Jun 26, 2017

  • 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! :)

@killercup

This comment has been minimized.

Member

killercup commented Jun 26, 2017

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"] }
@killercup

This comment has been minimized.

Member

killercup commented Jun 26, 2017

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.

@elliotekj

This comment has been minimized.

elliotekj commented Jun 26, 2017

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 :)

@killercup

This comment has been minimized.

Member

killercup commented Jun 26, 2017

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

lol 😅

@elliotekj

This comment has been minimized.

elliotekj commented Jun 26, 2017

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.

@killercup

This comment has been minimized.

Member

killercup commented Jun 26, 2017

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.)

@elliotekj

This comment has been minimized.

elliotekj commented Jun 26, 2017

@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 😄

@killercup

This comment has been minimized.

Member

killercup commented Jun 26, 2017

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™ :)

@killercup killercup closed this Jun 26, 2017

@elliotekj

This comment has been minimized.

elliotekj commented Jul 5, 2017

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

@sgrif

This comment has been minimized.

Member

sgrif commented Jul 5, 2017

Thanks for confirming. ❤️

@vityafx

This comment has been minimized.

vityafx commented Jul 11, 2017

@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"]
@killercup

This comment has been minimized.

Member

killercup commented Jul 11, 2017

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

@vityafx

This comment has been minimized.

vityafx commented Jul 11, 2017

@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.

@killercup

This comment has been minimized.

Member

killercup commented Jul 11, 2017

Rocket 0.3 will include it: SergioBenitez/Rocket#273 (comment)

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

@vityafx

This comment has been minimized.

vityafx commented Jul 11, 2017

@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!

@greenpdx

This comment has been minimized.

greenpdx commented Nov 25, 2017

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

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:
<models::chrono::NaiveDateTime as diesel::types::FromSqlRow<diesel::types::Timestamp, DB>>
<models::chrono::NaiveDateTime as diesel::types::FromSqlRow<diesel::types::Timestamptz, DB>>
= 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

@weiznich

This comment has been minimized.

Contributor

weiznich commented Nov 25, 2017

@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>.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment