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

[E0277]: the trait bound `i32: diesel::types::FromSqlRow<diesel::types::Nullable<diesel::types::Integer>, diesel::pg::Pg>` is not satisfied #330

Closed
fuyingfuying opened this Issue May 15, 2016 · 9 comments

Comments

Projects
None yet
4 participants
@fuyingfuying

fuyingfuying commented May 15, 2016

2016-05-15 11-48-45
Hello, when I try to use diesel to build my first orm, and error is come. My way is exactly same to your getting-start doc.
up.sql:

CREATE TABLE USERS (
    uid VARCHAR PRIMARY KEY,
    realname VARCHAR NOT NULL,
    age INTEGER,
    sex VARCHAR
);

down.sql:

DROP TABLE USERS;

.env:

DATABASE_URL=postgres://postgres:postgres@localhost/simllsan

and the command diesel migration redo has been executed successfully :

fuying@fuying-linux:~/rustprojs/simtraining$ diesel migration redo
Rolling back migration 20160514210851
Running migration 20160514210851

lib.rs:

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

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

extern crate serde;
extern crate serde_json;

extern crate time;
extern crate rand;
extern crate libc;
extern crate mio;
#[cfg(windows)]
extern crate winapi;
#[cfg(windows)]
extern crate ws2_32;

pub mod jizu;
pub mod simctrl;
pub mod util;
pub mod zhiling;
pub mod dianzhan;
pub mod duanluqi;
pub mod fuzai;
pub mod node;
pub mod zhilu;
pub mod xitong;

pub mod schema;
pub mod user;
// pub mod evaluation;
// pub mod projects;
// pub mod station;
// pub mod training;
use diesel::prelude::*;
use diesel::pg::PgConnection;
use dotenv::dotenv;
use std::env;
use diesel::result::Error;
use user::{User, NewUser};

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

pub fn create_user<'a>(conn: &PgConnection,
                  _uid: &'a str,
                  _realname: &'a str,
                  _age: i32,
                  _sex: &'a str)
                  -> QueryResult<User> {
    use schema::users;
    let uid_s = String::from(_uid);

    let result = users::table.find(uid_s).first(conn);
    match result {
        Err(NotFound) => {
            let new_user = NewUser {
                uid: _uid,
                realname: _realname,
                age : _age,
                sex : _sex,
            };
            return diesel::insert(&new_user).into(users::table)
                .get_result(conn);
        }
        Ok(_) => return Err(Error::DatabaseError("此用户名已存在".to_string())),
    }
}

schema.rs:

infer_schema!(dotenv!("DATABASE_URL"));

user.rs:

use super::schema::users;
#[derive(PartialEq, Copy, Clone, Debug, Serialize, Deserialize)]
pub enum Sex {
    Male,
    Female,
    Unisex,
}
#[derive(PartialEq, Clone, Debug, Serialize, Deserialize, Queryable)]
pub struct User {
    pub uid: String,
    pub realname: String,
    pub age: i32,
    pub sex: String,
}

#[insertable_into(users)]
pub struct NewUser<'a> {
    pub uid: &'a str,
    pub realname: &'a str,
    pub age: i32,
    pub sex: &'a str,
}

impl User {
    pub fn new(_id: &str, _realname: &str) -> User {
        User {
            uid: String::from(_id),
            realname: String::from(_realname),
            age: 0,
            sex: "".to_string(),
        }
    }

}
@fuyingfuying

This comment has been minimized.

fuyingfuying commented May 15, 2016

I use ubuntu 15.10, and the version of rust is:

fuying@fuying-linux:~/rustprojs/simtraining$ rustc --version
rustc 1.10.0-nightly (d91f8ab0f 2016-05-07)
fuying@fuying-linux:~/rustprojs/simtraining$ cargo --version
cargo 0.11.0-nightly (b304305 2016-05-06)

cargo.toml:

[package]
name = "simtraining"
version = "0.1.0"
authors = ["fuying"]

[dependencies]
time = "^0.1"
rand = "^0.3"
libc = "^0.2"
mio = "^0.5"
serde = "^0.7.0"
serde_json = "^0.7.0"
serde_macros = "^0.7.0"
iron = "^0.3.0"
router = "^0.1.1"
diesel = { git = "https://github.com/diesel-rs/diesel.git" }
diesel_codegen = { git = "https://github.com/diesel-rs/diesel.git", default-features = false, features = ["nightly", "postgres"] }
dotenv = "^0.8.0"
dotenv_macros = "^0.8.0"

[dev-dependencies]
rand = "^0.3"

[target.x86_64-pc-windows-msvc.dependencies]
winapi = "^0.2"
ws2_32-sys = "^0.2"
[target.x86_64-pc-windows-gnu.dependencies]
winapi = "^0.2"
ws2_32-sys = "^0.2"
[target.i686-pc-windows-msvc.dependencies]
winapi = "^0.2"
ws2_32-sys = "^0.2"

[[example]]
name = "test-router"
path = "examples/testrouter.rs"

[[example]]
name = "test-create-user"
path = "examples/testcreateuser.rs"
@sgrif

This comment has been minimized.

Member

sgrif commented May 15, 2016

This is correct. You cannot deserialize a column of type Nullable<Integer> into an i32. You'll either need to use an Option<i32> on the Rust side, or change the field to be NOT NULL on the SQL side.

@sgrif sgrif closed this May 15, 2016

@fuyingfuying

This comment has been minimized.

fuyingfuying commented May 15, 2016

@sgrif
thank you very much

@fuyingfuying

This comment has been minimized.

fuyingfuying commented May 15, 2016

@sgrif
sorry to bother you. Another question is how can i deserialize an embedded struct obiect? It likes this:
#[derive(Queryable)]
#[insert_into(users)]
struct User {
//...
}

#[derive(Queryable)]
#[insert_into(posts)]
struct Post {
//...
user : User
}

Does it correct? Because I am outside and can't test it. So if you are not busy, please help me.
By the way, does diesel support json or jsonb type? And if diesel can support it, where can I find its docs and how to use it? Thank you very much.

@sgrif

This comment has been minimized.

Member

sgrif commented May 15, 2016

We don't really have support for embedded structs at the moment. When you're querying against two tables, you'd get back a (Post, User) instead of embedding the parent record inside of the child. If you really want to embed a struct, you'll need to implement FromSqlRow for your User struct manually. It'd look something like this:

use diesel::prelude::*;
use diesel::backend::Backend;
use diesel::types::{FromSqlRow + HasSqlType};
use diesel::row::Row;
use std::error::Error;

impl<ST, DB> FromSqlRow<ST, DB> for User where
    DB: Backend + HasSqlType<ST>,
    User: Queryable<ST, DB>,
    <User as Queryable<ST, DB>>::Row: FromSqlRow<ST, DB>,
{
    fn build_from_row<T: Row<DB>>(row: &mut T) -> Result<Self, Box<Error + Send + Sync>> {
        let row = try!(<<User as Queryable<ST, DB>>::Row as FromSqlRow<ST, DB>>::build_from_row(row));
        Ok(User::build(row))
    }
}

Note: Haven't tried that exact code, that's just from memory of what it'd roughly look like.

We don't support the JSON type yet, but it's on the radar for something we'd like to support. #44 is the tracking issue, and I've mentioned how you could use it today in your app if needed in the comments there.

@fuyingfuying

This comment has been minimized.

fuyingfuying commented May 15, 2016

@sgrif
thank you very much.

1 similar comment
@fuyingfuying

This comment has been minimized.

fuyingfuying commented May 15, 2016

@sgrif
thank you very much.

@tmahmood

This comment has been minimized.

tmahmood commented Jul 22, 2017

Just a note, I faced similar issue. it's important that after you've made changes to the migration, run

cargo clean

From my limited understanding, I assume the custom code generator does not update the generated code and uses the old database definition, So we need to clean the generated code

I am sorry, for least clear explanation as I'm sleepy and just figured out the problem. I hope it helps someone.

@theredfish

This comment has been minimized.

theredfish commented Sep 3, 2017

@tmahmood thank you :) your solution solved my issue

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