Skip to content

Commit

Permalink
Postgres insert many will throw RecordNotInserted error if non of the…
Browse files Browse the repository at this point in the history
…m are being inserted (#1021)
  • Loading branch information
billy1624 authored Jan 11, 2023
1 parent 4f5a15a commit b5e984c
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 1 deletion.
5 changes: 5 additions & 0 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,11 @@ pub enum DbErr {
/// A migration error
#[error("Migration Error: {0}")]
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
Expand Down
5 changes: 4 additions & 1 deletion src/executor/insert.rs
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,10 @@ where
let cols = PrimaryKey::<A>::iter()
.map(|col| col.to_string())
.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()
}
false => {
Expand Down
65 changes: 65 additions & 0 deletions tests/upsert_tests.rs
Original file line number Diff line number Diff line change
@@ -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(())
}

0 comments on commit b5e984c

Please sign in to comment.