Rust diesel orm查询
Rust diesel orm queries
我是生锈和柴油机的新手。我正在尝试在我的查询中执行以下操作:
- 计数
- select
- 订单
- 限制
但我收到错误消息。
我正在使用 postgres 数据库。
我在评论中的查询上方添加了准确的错误。
这是我的代码:
schema.rs
table! {
employee (employee_id) {
employee_id -> Int4,
name -> Nullable<Text>,
age -> Nullable<Int4>,
address -> Nullable<Text>,
email -> Nullable<Text>,
dept_id -> Int4,
salary -> Nullable<Numeric>,
created_on -> Nullable<Timestamp>,
created_by -> Nullable<Text>,
modified_on -> Nullable<Timestamp>,
modified_by -> Nullable<Text>,
is_active -> Nullable<Bool>,
}
}
models.rs
#![allow(unused)]
#![allow(clippy::all)]
use super::schema::employee;
use bigdecimal::BigDecimal;
use chrono::NaiveDateTime;
#[derive(Queryable, Debug, Identifiable)]
#[table_name = "employee"]
#[primary_key(employee_id)]
pub struct Employee {
pub employee_id: i32,
pub name: Option<String>,
pub age: Option<i32>,
pub address: Option<String>,
pub email: Option<String>,
pub dept_id: i32,
pub salary: Option<BigDecimal>,
pub created_on: Option<NaiveDateTime>,
pub created_by: Option<String>,
pub modified_on: Option<NaiveDateTime>,
pub modified_by: Option<String>,
pub is_active: Option<bool>,
}
cargo.toml
[dependencies]
diesel = { version = "1.4.5", features = ["postgres","chrono","numeric"] }
dotenv = "0.15.0"
chrono = { version = "0.4.19" , features = ["serde"] }
bigdecimal = { version = "0.1.0" }
main.rs
#[macro_use]
extern crate diesel;
extern crate bigdecimal;
extern crate chrono;
extern crate dotenv;
use crate::models::Employee;
use crate::models::Players;
use crate::schema::employee::dsl::*;
use diesel::{pg::PgConnection, prelude::*};
use dotenv::dotenv;
use std::env;
mod models;
mod schema;
fn main() {
dotenv().ok();
let data_url: String = env::var("DATABASE_URL").expect("DATABASE_URL must be set");
let connection: PgConnection =
PgConnection::establish(&data_url).expect(&format!("Error connect to {}", data_url));
//get all employees name
//This is working fine
let _employee: Vec<Employee> = employee
.load::<Employee>(&connection)
.expect("Error loading department");
for emp in _employee {
println!("{}", emp.name.unwrap_or_default());
}
//----------------------------------------------
//get employees count
/*
Error: error[E0282]: type annotations needed
^^^^^^^^^^^^^^^ consider giving `total_employees` a type
*/
let total_employees = employee.count().get_result(&connection).expect("Error");
println!("{}", total_employees);
//-----------------------------------------------
//get all names
/*
Error: error[E0277]: the trait bound `*const str: FromSql<diesel::sql_types::Nullable<diesel::sql_types::Text>, _>` is not satisfied
^^^^ the trait `FromSql<diesel::sql_types::Nullable<diesel::sql_types::Text>, _>` is not implemented for `*const str`
*/
let all_names = employee.select(name).load::<String>(&connection)?;
println!("{}", all_names);
//----------------------------------------------
//order name
/*
Error: error[E0277]: the trait bound `*const str: FromSql<diesel::sql_types::Nullable<diesel::sql_types::Text>, _>` is not satisfied
^^^^ the trait `FromSql<diesel::sql_types::Nullable<diesel::sql_types::Text>, _>` is not implemented for `*const str`
*/
let ordered_names = employee
.select(name)
.order(name.desc())
.load::<String>(&connection)?;
println!("{}", ordered_names);
//------------------------------------------------
/*
Error: error[E0277]: the trait bound `*const str: FromSql<diesel::sql_types::Nullable<diesel::sql_types::Text>, _>` is not satisfied
^^^^ the trait `FromSql<diesel::sql_types::Nullable<diesel::sql_types::Text>, _>` is not implemented for `*const str`
*/
let limited = employee
.select(name)
.order(employee_id)
.limit(1)
.load::<String>(&connection)?;
println!("{}", limited);
}
我错过了什么吗?
有人可以纠正我吗?
谢谢!
let total_employees = employee.count().get_result(&connection).expect("Error");
对于这个,尝试注释 total_employees
,像这样:
let total_employees: u64 = employee.count().get_result(&connection).expect("Error");
这将帮助您继续。即使该函数不是 return 这样的类型,错误现在至少会告诉您它是什么类型。
首先:您的代码缺少一个关键信息来实际重现那里描述的问题。在不知道您的底层数据库架构的情况下,只能猜测它的外观。对于我的回答,我将采用以下架构:
table! {
employee(employee_id) {
employee_id -> Integer,
name -> Nullable<Text>,
age -> Nullable<Integer>,
address -> Nullable<Text>,
email -> Nullable<Text>,
dept_id -> Integer,
salary -> Nullable<Numeric>,
created_on -> Nullable<Timestamp>,
created_by -> Nullable<Text>,
modified_on -> Nullable<Timestamp>,
modified_by -> Nullable<Text>,
is_active -> Nullable<Bool>,
}
}
现在作为一般规则:Diesel 使用此定义作为事实来源并且仅支持某些类型映射。如果您遇到编译错误,这可能意味着以下情况之一是错误的:
- 您已尝试将查询结果映射到包含某些 returned 列
的不兼容字段的结构
- 您已尝试将查询结果映射到包含比您的查询return
更多或更少字段的结构
回答您的特定错误消息:
//----------------------------------------------
//get employees count
/*
Error: error[E0282]: type annotations needed
^^^^^^^^^^^^^^^ consider giving `total_employees` a type
*/
let total_employees = employee.count().get_result(&connection).expect("Error");
println!("{}", total_employees);
Rustc 需要知道 total_employees
的类型,因为 get_result
return 是泛型,而 println
使用泛型。 Rustc 需要确切地知道应该在那里使用哪种类型。现在柴油文档在这里关于什么是正确的 return 类型有点稀疏,但是 Daniel Porteous
中的错误消息表明此查询 returns a BigInt
,它与i64
记录 here。这意味着这个查询可以工作:
let total_employees: i64 = employee.count().get_result(&connection).expect("Error");
您接下来的三个查询基本上无法编译并出现相同的错误消息:
//-----------------------------------------------
//get all names
/*
Error: error[E0277]: the trait bound `*const str: FromSql<diesel::sql_types::Nullable<diesel::sql_types::Text>, _>` is not satisfied
^^^^ the trait `FromSql<diesel::sql_types::Nullable<diesel::sql_types::Text>, _>` is not implemented for `*const str`
*/
let all_names = employee.select(name).load::<String>(&connection)?;
println!("{}", all_names);
//----------------------------------------------
//order name
/*
Error: error[E0277]: the trait bound `*const str: FromSql<diesel::sql_types::Nullable<diesel::sql_types::Text>, _>` is not satisfied
^^^^ the trait `FromSql<diesel::sql_types::Nullable<diesel::sql_types::Text>, _>` is not implemented for `*const str`
*/
let ordered_names = employee
.select(name)
.order(name.desc())
.load::<String>(&connection)?;
println!("{}", ordered_names);
//------------------------------------------------
/*
Error: error[E0277]: the trait bound `*const str: FromSql<diesel::sql_types::Nullable<diesel::sql_types::Text>, _>` is not satisfied
^^^^ the trait `FromSql<diesel::sql_types::Nullable<diesel::sql_types::Text>, _>` is not implemented for `*const str`
*/
let limited = employee
.select(name)
.order(employee_id)
.limit(1)
.load::<String>(&connection)?;
println!("{}", limited);
现在,此错误消息表明您尝试将由查询 return 编辑的字段映射到 Rust 端的不兼容类型。在这种情况下,不支持将不是 NOT NULL
的 Text
字段映射到 String
,因为柴油在这种情况下如何表示 NULL
值。 documentation states,您需要将可为 null 的类型包装在 Option
中。这意味着如果您将 return 类型更改为 Option<String>
在所有情况下一切都会成功编译。
我是生锈和柴油机的新手。我正在尝试在我的查询中执行以下操作:
- 计数
- select
- 订单
- 限制
但我收到错误消息。
我正在使用 postgres 数据库。
我在评论中的查询上方添加了准确的错误。
这是我的代码:
schema.rs
table! {
employee (employee_id) {
employee_id -> Int4,
name -> Nullable<Text>,
age -> Nullable<Int4>,
address -> Nullable<Text>,
email -> Nullable<Text>,
dept_id -> Int4,
salary -> Nullable<Numeric>,
created_on -> Nullable<Timestamp>,
created_by -> Nullable<Text>,
modified_on -> Nullable<Timestamp>,
modified_by -> Nullable<Text>,
is_active -> Nullable<Bool>,
}
}
models.rs
#![allow(unused)]
#![allow(clippy::all)]
use super::schema::employee;
use bigdecimal::BigDecimal;
use chrono::NaiveDateTime;
#[derive(Queryable, Debug, Identifiable)]
#[table_name = "employee"]
#[primary_key(employee_id)]
pub struct Employee {
pub employee_id: i32,
pub name: Option<String>,
pub age: Option<i32>,
pub address: Option<String>,
pub email: Option<String>,
pub dept_id: i32,
pub salary: Option<BigDecimal>,
pub created_on: Option<NaiveDateTime>,
pub created_by: Option<String>,
pub modified_on: Option<NaiveDateTime>,
pub modified_by: Option<String>,
pub is_active: Option<bool>,
}
cargo.toml
[dependencies]
diesel = { version = "1.4.5", features = ["postgres","chrono","numeric"] }
dotenv = "0.15.0"
chrono = { version = "0.4.19" , features = ["serde"] }
bigdecimal = { version = "0.1.0" }
main.rs
#[macro_use]
extern crate diesel;
extern crate bigdecimal;
extern crate chrono;
extern crate dotenv;
use crate::models::Employee;
use crate::models::Players;
use crate::schema::employee::dsl::*;
use diesel::{pg::PgConnection, prelude::*};
use dotenv::dotenv;
use std::env;
mod models;
mod schema;
fn main() {
dotenv().ok();
let data_url: String = env::var("DATABASE_URL").expect("DATABASE_URL must be set");
let connection: PgConnection =
PgConnection::establish(&data_url).expect(&format!("Error connect to {}", data_url));
//get all employees name
//This is working fine
let _employee: Vec<Employee> = employee
.load::<Employee>(&connection)
.expect("Error loading department");
for emp in _employee {
println!("{}", emp.name.unwrap_or_default());
}
//----------------------------------------------
//get employees count
/*
Error: error[E0282]: type annotations needed
^^^^^^^^^^^^^^^ consider giving `total_employees` a type
*/
let total_employees = employee.count().get_result(&connection).expect("Error");
println!("{}", total_employees);
//-----------------------------------------------
//get all names
/*
Error: error[E0277]: the trait bound `*const str: FromSql<diesel::sql_types::Nullable<diesel::sql_types::Text>, _>` is not satisfied
^^^^ the trait `FromSql<diesel::sql_types::Nullable<diesel::sql_types::Text>, _>` is not implemented for `*const str`
*/
let all_names = employee.select(name).load::<String>(&connection)?;
println!("{}", all_names);
//----------------------------------------------
//order name
/*
Error: error[E0277]: the trait bound `*const str: FromSql<diesel::sql_types::Nullable<diesel::sql_types::Text>, _>` is not satisfied
^^^^ the trait `FromSql<diesel::sql_types::Nullable<diesel::sql_types::Text>, _>` is not implemented for `*const str`
*/
let ordered_names = employee
.select(name)
.order(name.desc())
.load::<String>(&connection)?;
println!("{}", ordered_names);
//------------------------------------------------
/*
Error: error[E0277]: the trait bound `*const str: FromSql<diesel::sql_types::Nullable<diesel::sql_types::Text>, _>` is not satisfied
^^^^ the trait `FromSql<diesel::sql_types::Nullable<diesel::sql_types::Text>, _>` is not implemented for `*const str`
*/
let limited = employee
.select(name)
.order(employee_id)
.limit(1)
.load::<String>(&connection)?;
println!("{}", limited);
}
我错过了什么吗?
有人可以纠正我吗?
谢谢!
let total_employees = employee.count().get_result(&connection).expect("Error");
对于这个,尝试注释 total_employees
,像这样:
let total_employees: u64 = employee.count().get_result(&connection).expect("Error");
这将帮助您继续。即使该函数不是 return 这样的类型,错误现在至少会告诉您它是什么类型。
首先:您的代码缺少一个关键信息来实际重现那里描述的问题。在不知道您的底层数据库架构的情况下,只能猜测它的外观。对于我的回答,我将采用以下架构:
table! {
employee(employee_id) {
employee_id -> Integer,
name -> Nullable<Text>,
age -> Nullable<Integer>,
address -> Nullable<Text>,
email -> Nullable<Text>,
dept_id -> Integer,
salary -> Nullable<Numeric>,
created_on -> Nullable<Timestamp>,
created_by -> Nullable<Text>,
modified_on -> Nullable<Timestamp>,
modified_by -> Nullable<Text>,
is_active -> Nullable<Bool>,
}
}
现在作为一般规则:Diesel 使用此定义作为事实来源并且仅支持某些类型映射。如果您遇到编译错误,这可能意味着以下情况之一是错误的:
- 您已尝试将查询结果映射到包含某些 returned 列 的不兼容字段的结构
- 您已尝试将查询结果映射到包含比您的查询return 更多或更少字段的结构
回答您的特定错误消息:
//----------------------------------------------
//get employees count
/*
Error: error[E0282]: type annotations needed
^^^^^^^^^^^^^^^ consider giving `total_employees` a type
*/
let total_employees = employee.count().get_result(&connection).expect("Error");
println!("{}", total_employees);
Rustc 需要知道 total_employees
的类型,因为 get_result
return 是泛型,而 println
使用泛型。 Rustc 需要确切地知道应该在那里使用哪种类型。现在柴油文档在这里关于什么是正确的 return 类型有点稀疏,但是 Daniel Porteous
中的错误消息表明此查询 returns a BigInt
,它与i64
记录 here。这意味着这个查询可以工作:
let total_employees: i64 = employee.count().get_result(&connection).expect("Error");
您接下来的三个查询基本上无法编译并出现相同的错误消息:
//-----------------------------------------------
//get all names
/*
Error: error[E0277]: the trait bound `*const str: FromSql<diesel::sql_types::Nullable<diesel::sql_types::Text>, _>` is not satisfied
^^^^ the trait `FromSql<diesel::sql_types::Nullable<diesel::sql_types::Text>, _>` is not implemented for `*const str`
*/
let all_names = employee.select(name).load::<String>(&connection)?;
println!("{}", all_names);
//----------------------------------------------
//order name
/*
Error: error[E0277]: the trait bound `*const str: FromSql<diesel::sql_types::Nullable<diesel::sql_types::Text>, _>` is not satisfied
^^^^ the trait `FromSql<diesel::sql_types::Nullable<diesel::sql_types::Text>, _>` is not implemented for `*const str`
*/
let ordered_names = employee
.select(name)
.order(name.desc())
.load::<String>(&connection)?;
println!("{}", ordered_names);
//------------------------------------------------
/*
Error: error[E0277]: the trait bound `*const str: FromSql<diesel::sql_types::Nullable<diesel::sql_types::Text>, _>` is not satisfied
^^^^ the trait `FromSql<diesel::sql_types::Nullable<diesel::sql_types::Text>, _>` is not implemented for `*const str`
*/
let limited = employee
.select(name)
.order(employee_id)
.limit(1)
.load::<String>(&connection)?;
println!("{}", limited);
现在,此错误消息表明您尝试将由查询 return 编辑的字段映射到 Rust 端的不兼容类型。在这种情况下,不支持将不是 NOT NULL
的 Text
字段映射到 String
,因为柴油在这种情况下如何表示 NULL
值。 documentation states,您需要将可为 null 的类型包装在 Option
中。这意味着如果您将 return 类型更改为 Option<String>
在所有情况下一切都会成功编译。