Postgres insert many will throw RecordNotInserted error if non of them are being inserted (#1021)

This commit is contained in:
Billy Chan 2023-01-11 14:16:35 +08:00 committed by GitHub
parent 4f5a15a99f
commit b5e984ca4a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 74 additions and 1 deletions

View File

@ -55,6 +55,11 @@ pub enum DbErr {
/// A migration error /// A migration error
#[error("Migration Error: {0}")] #[error("Migration Error: {0}")]
Migration(String), Migration(String),
/// None of the records are being inserted into the database,
/// if you insert with upsert expression that means
/// all of them conflict with existing records in the database
#[error("RecordNotInserted Error: {0}")]
RecordNotInserted(String),
} }
/// Runtime error /// Runtime error

View File

@ -142,7 +142,10 @@ where
let cols = PrimaryKey::<A>::iter() let cols = PrimaryKey::<A>::iter()
.map(|col| col.to_string()) .map(|col| col.to_string())
.collect::<Vec<_>>(); .collect::<Vec<_>>();
let res = db.query_one(statement).await?.unwrap(); let rows = db.query_all(statement).await?;
let res = rows.last().ok_or_else(|| {
DbErr::RecordNotInserted("None of the records are being inserted".to_owned())
})?;
res.try_get_many("", cols.as_ref()).ok() res.try_get_many("", cols.as_ref()).ok()
} }
false => { false => {

65
tests/upsert_tests.rs Normal file
View File

@ -0,0 +1,65 @@
pub mod common;
pub use common::{features::*, setup::*, TestContext};
use pretty_assertions::assert_eq;
use sea_orm::entity::prelude::*;
use sea_orm::{sea_query::OnConflict, Set};
#[sea_orm_macros::test]
#[cfg(feature = "sqlx-postgres")]
async fn main() -> Result<(), DbErr> {
let ctx = TestContext::new("upsert_tests").await;
create_tables(&ctx.db).await?;
create_insert_default(&ctx.db).await?;
ctx.delete().await;
Ok(())
}
pub async fn create_insert_default(db: &DatabaseConnection) -> Result<(), DbErr> {
use insert_default::*;
let on_conflict = OnConflict::column(Column::Id).do_nothing().to_owned();
let res = Entity::insert_many([
ActiveModel { id: Set(1) },
ActiveModel { id: Set(2) },
ActiveModel { id: Set(3) },
])
.on_conflict(on_conflict.clone())
.exec(db)
.await;
assert_eq!(res?.last_insert_id, 3);
let res = Entity::insert_many([
ActiveModel { id: Set(1) },
ActiveModel { id: Set(2) },
ActiveModel { id: Set(3) },
ActiveModel { id: Set(4) },
])
.on_conflict(on_conflict.clone())
.exec(db)
.await;
assert_eq!(res?.last_insert_id, 4);
let res = Entity::insert_many([
ActiveModel { id: Set(1) },
ActiveModel { id: Set(2) },
ActiveModel { id: Set(3) },
ActiveModel { id: Set(4) },
])
.on_conflict(on_conflict)
.exec(db)
.await;
assert_eq!(
res.err(),
Some(DbErr::RecordNotInserted(
"None of the records are being inserted".to_owned()
))
);
Ok(())
}