2

我无法让柴油在 Rust 上运行。这个项目的背景是一个使用 postgres 作为服务器来保存分数和使用柴油访问 postgres 的分数统计系统。当我在 models.rs (命名Score)中定义一个结构时,我得到这个错误:

error[E0433]: failed to resolve: use of undeclared type or module `scores`
 --> src/models.rs:7:16
  |
7 | #[table_name = "scores"]
  |                ^^^^^^^^ use of undeclared type or module `scores`

schema.rs 的内容是:

table! {
    scores (name) {
        name -> Varchar,
        points -> Nullable<Int4>,
        subject -> Nullable<Varchar>,
    }
}

这是我的models.rs:

#[macro_use]
use diesel::*;
use diesel::sql_types::*;
use crate::schema::scores::*;

#[derive(Queryable, Insertable, QueryableByName)]
#[table_name = "scores"]
pub struct Score {
    #[sql_type = "Varchar"]
    name: String,
    #[sql_type = "Integer"]
    points: Option<i32>,
    #[sql_type = "Varchar"]
    subject: Option<String>,
}

我正在尝试使用 add_entry.rs 向其中添加条目:

use super::models::Score;
use diesel::pg::PgConnection;
use crate::schema::*;

pub fn create_score(conn: PgConnection, name: String, score: i32, subject: String) -> () {
    let new_score = Score {
        name: name,
        points: Some(score),
        subject: Some(subject),
    };   

    let ins = diesel::insert_into(scores::table)
        .values(new_score)
        .execute(&conn);
}

在 main.rs 中,我有:

#[macro_use] extern crate diesel;
mod add_entry;
mod connect;
mod models;
mod schema;
use diesel::dsl::sql_query;

fn main() {
    let conn = connect::connect();
    let name = String::from("name");
    let subject = String::from("subject");
    add_entry::create_score(conn, name.clone(), 75, subject.clone());
    //random data
    list_score();
}

fn list_score() {
    let connection = connect::connect();
    let result = sql_query("SELECT * FROM scores");
    println!("{:#?}", result);
}

在connect.rs(与服务器连接)中,我有:

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

pub fn connect() -> PgConnection {
     dotenv().ok();
     let database_url = env::var("DATABASE_URL")
         .expect("Cannot get DB URL.");
     PgConnection::establish(&database_url)
         .expect(&format!("Error connecting to {}", database_url));
}

我的 Cargo.toml 的依赖部分的内容是

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

为了得到这个错误,我跑来diesel setup设置一切,,,,diesel migration run再次diesel migration redodiesel migration run最后cargo build

我的完整代码可以在这个存储库中找到。

我应该怎么做才能消除这个错误?谢谢。

4

2 回答 2

1

简短回答:您需要导入use crate::schema::scores;而不是use crate::schema::scores::*;.

更长的解释:

Diesel 的table!宏生成一个相当复杂的模块结构,包含几种类型。此外,这些类型是从不同位置重新导出的,例如dsl模块。派生需要知道crate::schema::your_table::table每列的类型和所有类型(所以crate::schema::your_table::column_a,...)。由于它无法访问整个模块并且不知道范围内的类型,因此柴油需要以某种方式推断该类型。最简单的方法是从某个地方获取模块名称。这是通过#[table_name = "your_table"]属性完成的,该属性假定模块your_table在包含表和列的相应类型的范围内。

有关更多详细信息,请查看以下文档:

于 2020-03-21T18:12:43.923 回答
-1

如果您的架构包含可为空的字段,您需要Option<T>对此类字段使用 on rust 端:

#[macro_use]
use diesel::*;

use crate::schema::scores;

#[derive(Queryable, Insertable)]
//#[table_name = "scores"]
pub struct Score {
    //#[sql_type = "Varchar"]
    pub name: String,
    //#[sql_type = "Integer"]
    pub points: Option<i32>,
    //#[sql_type = "Varchar"]
    pub subject: Option<String>,
    //#[sql_type = "Varchar"]
    pub date: Option<String>,
}

并且在使用时diesel::insert_into记得导入schema::scores.

add_entry.rs

use super::models::Score;
use crate::schema::scores;
use diesel::pg::PgConnection;
use diesel::prelude::*;

pub fn create_score(
    conn: PgConnection,
    name: String,
    score: i32,
    subject: String,
    date: String,
) -> () {
    let new_score = Score {
        name: name,
        points: Some(score),
        subject: Some(subject),
        date: Some(date),
    };

    let ins = diesel::insert_into(scores::table)
        .values(new_score)
        .execute(&conn);
}

如果您解决了使用移动值引起的问题,main.rs您现在可以编译您的项目。

add_entry::create_score(
    connection,
    option.clone(),
    scores,
    subject.clone(),
    date.clone(),
);
于 2020-03-17T13:57:21.057 回答