set unselected Column of type Option<T> to None (#1513)

* Support `None` value for unselected Optional columns, closes #1507

* Support `None` value for unselected Optional columns, closes #1507

* fix rustfmt and cfg control issues

* add test case for #1513
This commit is contained in:
Reverier 2023-03-16 21:24:58 +08:00 committed by GitHub
parent 02b6afbb02
commit 1161bc0f4a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 48 additions and 1 deletions

View File

@ -140,6 +140,10 @@ impl<T: TryGetable> TryGetable for Option<T> {
match T::try_get_by(res, index) { match T::try_get_by(res, index) {
Ok(v) => Ok(Some(v)), Ok(v) => Ok(Some(v)),
Err(TryGetError::Null(_)) => Ok(None), Err(TryGetError::Null(_)) => Ok(None),
#[cfg(feature = "sqlx-dep")]
Err(TryGetError::DbErr(DbErr::Query(RuntimeErr::SqlxError(
sqlx::Error::ColumnNotFound(_),
)))) => Ok(None),
Err(e) => Err(e), Err(e) => Err(e),
} }
} }

View File

@ -2,7 +2,7 @@ pub mod common;
pub use common::{bakery_chain::*, setup::*, TestContext}; pub use common::{bakery_chain::*, setup::*, TestContext};
pub use sea_orm::entity::*; pub use sea_orm::entity::*;
pub use sea_orm::{ConnectionTrait, QueryFilter}; pub use sea_orm::{ConnectionTrait, QueryFilter, QuerySelect};
// Run the test locally: // Run the test locally:
// DATABASE_URL="mysql://root:@localhost" cargo test --features sqlx-mysql,runtime-async-std --test query_tests // DATABASE_URL="mysql://root:@localhost" cargo test --features sqlx-mysql,runtime-async-std --test query_tests
@ -222,3 +222,46 @@ pub async fn find_all_filter_with_results() {
ctx.delete().await; ctx.delete().await;
} }
#[sea_orm_macros::test]
#[cfg(any(
feature = "sqlx-mysql",
feature = "sqlx-sqlite",
feature = "sqlx-postgres"
))]
pub async fn select_only_exclude_option_fields() {
let ctx = TestContext::new("select_only_exclude_option_fields").await;
create_tables(&ctx.db).await.unwrap();
let _ = customer::ActiveModel {
name: Set("Alice".to_owned()),
notes: Set(Some("Want to communicate with Bob".to_owned())),
..Default::default()
}
.save(&ctx.db)
.await
.expect("could not insert customer");
let _ = customer::ActiveModel {
name: Set("Bob".to_owned()),
notes: Set(Some("Just listening".to_owned())),
..Default::default()
}
.save(&ctx.db)
.await
.expect("could not insert customer");
let customers = Customer::find()
.select_only()
.column(customer::Column::Id)
.column(customer::Column::Name)
.all(&ctx.db)
.await
.unwrap();
assert_eq!(customers.len(), 2);
assert_eq!(customers[0].notes, None);
assert_eq!(customers[1].notes, None);
ctx.delete().await;
}