使用 Diesel 从 mySQL 数据库中检索日期时间
Posted
技术标签:
【中文标题】使用 Diesel 从 mySQL 数据库中检索日期时间【英文标题】:Retrieve datetime from mySQL database using Diesel 【发布时间】:2018-08-30 22:54:33 【问题描述】:我无法使用 Rocket 和 Diesel 从填充的 mysql 数据库中检索日期时间。
这是我的模型:
extern crate chrono;
use diesel::prelude::*;
use diesel::mysql::MysqlConnection;
use schema::chrisms;
use diesel::sql_types::Datetime;
use self::chrono::DateTime, Duration, NaiveDate, NaiveDateTime, NaiveTime, TimeZone, Utc;
#[derive(Serialize, Deserialize, Queryable)]
pub struct Chrisms
pub entity_ekklesia_location_id: i32,
pub serie_number: Option<String>,
pub seat_number: Option<String>,
pub date: Datetime,
pub year: i32,
pub deleted: bool,
pub entity_chrism_location_id: Option<i32>,
pub entity_chrism_location_description: Option<String>,
pub entity_rel_mec_id: Option<i32>,
pub entity_rel_mec_description: Option<String>,
pub created_by_user_id: Option<i32>,
pub updated_by_user_id: Option<i32>,
pub deleted_by_user_id: Option<i32>,
pub created_at: Datetime,
pub updated_at: Datetime,
pub id: i32,
impl Chrisms
pub fn read(connection: &MysqlConnection) -> Vec<Chrisms>
chrisms::table.load::<Chrisms>(connection).unwrap()
我的架构:
table!
chrisms (id)
entity_ekklesia_location_id -> Integer,
serie_number -> Nullable<Varchar>,
seat_number -> Nullable<Varchar>,
date -> Datetime,
year -> Integer,
deleted -> Bool,
entity_chrism_location_id -> Nullable<Integer>,
entity_chrism_location_description -> Nullable<Varchar>,
entity_rel_mec_id -> Nullable<Integer>,
entity_rel_mec_description -> Nullable<Varchar>,
created_by_user_id -> Nullable<Integer>,
updated_by_user_id -> Nullable<Integer>,
deleted_by_user_id -> Nullable<Integer>,
created_at -> Datetime,
updated_at -> Datetime,
id -> Integer,
这会产生错误:
1. the trait `_IMPL_SERIALIZE_FOR_TemplateContext::_serde::Serialize` is not
implemented for `diesel::sql_types::Datetime`
-required by `_IMPL_SERIALIZE_FOR_TemplateContext::_serde::ser::SerializeStruct::serialize_field`
2. the trait `_IMPL_SERIALIZE_FOR_TemplateContext::_serde::Deserialize<'_>` is
not implemented for `diesel::sql_types::Datetime`
- required by `_IMPL_SERIALIZE_FOR_TemplateContext::_serde::de::SeqAccess::next_element`
- required by `_IMPL_SERIALIZE_FOR_TemplateContext::_serde::de::MapAccess::next_value`
3. the trait `diesel::Queryable<diesel::sql_types::Datetime,
diesel::mysql::Mysql>` is not implemented for `diesel::sql_types::Datetime`
- required because of the requirements on the impl of `diesel::query_dsl::LoadQuery<_, models::chrisms::Chrisms>` for `schema::chrisms::table`
我该如何解决这个问题?我测试了一堆用法,比如diesel:mysql_types
、rocket:config
等等,似乎不是这个问题。
【问题讨论】:
您是否启用了 Diesel 的chrono
功能?
diesel = version = "1.0", features = ["mysql", "chrono"] 关于依赖项
@LeonelSá 我有这个,当我使用时使用 chrono::NaiveDateTime;在 model.rs 中我收到找不到模块的错误。它现在从柴油中去除了吗?
【参考方案1】:
diesel 创建/读取/更新/删除日期时间示例
Cargo.toml:
[dependencies]
diesel = version = "1.4", features = ["sqlite", "chrono"]
chrono = "0.4"
用户架构:
CREATE TABLE users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
email TEXT NOT NULL UNIQUE,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);
mod schema
table!
users (id)
id -> Integer,
email -> Text,
created_at -> Timestamp,
mod models
use super::schema::users;
#[derive(Queryable, Debug)]
pub struct User
pub id: i32,
pub email: String,
/// deisel create must enable chrono feature
/// Timestamp without timezone, the memory align of Timestamp type in sqlite is same as libc::timeval?
pub created_at: chrono::NaiveDateTime,
#[derive(Insertable)]
#[table_name = "users"]
pub struct UserInsert
pub email: String,
#[macro_use]
extern crate diesel;
use diesel::
result::Error as DieselError, sql_types::BigInt, sqlite::SqliteConnection, Connection,
ExpressionMethods, QueryDsl, RunQueryDsl,
;
use models::User, UserInsert;
use schema::users::dsl::created_at, id, users;
fn create_user(conn: &SqliteConnection, new_user_form: UserInsert) -> Result<User, DieselError>
// use sqlite(last_insert_rowid)/mysql(last_insert_id) to get current connection's last_insert_id
// use .order(id.desc()).last() will get the wrong id when multi db_connections insert at same time
no_arg_sql_function!(last_insert_rowid, BigInt);
diesel::insert_into(users)
.values(&new_user_form)
.execute(conn)?;
let new_user_id: i64 = diesel::select(last_insert_rowid).first(conn)?;
let last_insert_user: User = users.filter(id.eq(new_user_id as i32)).first(conn)?;
Ok(last_insert_user)
fn read_users(conn: &SqliteConnection) -> Result<Vec<User>, DieselError>
Ok(users.load::<User>(conn)?)
fn update_user_created_at(conn: &SqliteConnection, user_id: i32) -> Result<(), DieselError>
diesel::update(users.filter(id.eq(user_id)))
.set(created_at.eq(chrono::Utc::now().naive_utc()))
.execute(conn)?;
Ok(())
fn delete_user_by_user_id(conn: &SqliteConnection, user_id: i32) -> Result<(), DieselError>
diesel::delete(users.filter(id.eq(user_id))).execute(conn)?;
Ok(())
/// diesel CRUD(Create, Read, Update, Delete) example with datetime
fn main() -> Result<(), DieselError>
// TODO use r2d2 db_pool to enhance diesel performance
let conn = SqliteConnection::establish("file:db.sqlite").unwrap();
// clear all data before test
diesel::delete(users).execute(&conn)?;
let test_user_email = format!(
"test+@example.com",
std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.unwrap()
.as_secs()
);
// CRUD - Create
println!("\nCRUD - Create");
let last_insert_user = create_user(
&conn,
UserInsert
email: test_user_email,
,
)?;
dbg!(&last_insert_user);
// CRUD - Read
println!("\nCRUD - Read");
dbg!(read_users(&conn)?);
assert_eq!(read_users(&conn)?[0].id, last_insert_user.id);
// CRUD - Update
println!("\nCRUD - Update");
update_user_created_at(&conn, last_insert_user.id)?;
dbg!(read_users(&conn)?);
assert_ne!(read_users(&conn)?[0].created_at, last_insert_user.created_at);
// CRUD - Delete
println!("\nCRUD - Delete");
delete_user_by_user_id(&conn, last_insert_user.id)?;
dbg!(read_users(&conn)?);
assert!(read_users(&conn)?.is_empty());
Ok(())
输出示例:
CRUD - Create
[src/main.rs:85] &last_insert_user = User
id: 1,
email: "test+1606720099@example.com",
created_at: 2020-11-30T07:08:19,
CRUD - Read
[src/main.rs:88] read_users(&conn)? = [
User
id: 1,
email: "test+1606720099@example.com",
created_at: 2020-11-30T07:08:19,
,
]
CRUD - Update
[src/main.rs:93] read_users(&conn)? = [
User
id: 1,
email: "test+1606720099@example.com",
created_at: 2020-11-30T07:08:19.386513,
,
]
CRUD - Delete
[src/main.rs:98] read_users(&conn)? = []
【讨论】:
找了一个小时后,我找到了你的答案,而且效果很好。 ✌?以上是关于使用 Diesel 从 mySQL 数据库中检索日期时间的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 Diesel 和 SQLite 获取新创建值的 id?