Fix error of cleaning actions in slick dbio effects

I have a script below and I am trying to use DBlick slick actions to achieve it.

Execute a batch Insert operation. On success, return the inserted result On failure, -> if the failure is due to duplicate value in a particular column, then remove the duplicates from the list, and try batch insert again. If the second batch insert is successful, return a successful future with the second inserted list, else the failed future of the 2nd batch insert. -> if the failure is due to something else, then throw that exception 

In the above script, I tried using the cleanUp action. But I don’t know how to return the result of cleanUp actions if the main action failed.

How can I fulfill my requirement with DBIO error handling?

 def insertBatchAndReturnQuery(rowList: List[E]): FixedSqlAction[Seq[E], NoStream, Write] = { query returning query ++= rowList } def insert(entities: List[E]): Future[Seq[E]] = { val q = insertBatchAndReturnQuery(entities).cleanUp { case Some(ex) => ex match { case b: PSQLException => { if (b.getSQLState.equals("23505")) { //unique key exception, handle this by removing the duplicate entries from the list ??? } else { throw new Exception("some database exception") } } } case None => insertBatchAndReturnQuery(Nil) } db.run(q) } 

Here the query is TableQuery [T].

Slick Version: 3.2.0-M2

+6
source share
1 answer

You can see from the signature for cleanUp that it returns an action with a value of the same type as the first action, so you cannot return a value from the cleanUp action.

If you want to return the second value, you need to wrap your error in Try using asTry and then use flatMap . For this problem, it would look something like this:

 val q = insertBatchAndReturnQuery(entities).asTry.flatMap { case Failure(b: PSQLException) if b.getSQLState == "23505" => //unique key exception, handle this //by removing the duplicate entries from the list ??? case Failure(e) => throw new Exception("some database exception") case Success(count) => DBIO.successful(count) } 

However, the documentation warns that using asTry loses bandwidth, so you may find another way to do this ...

0
source

Source: https://habr.com/ru/post/1014756/


All Articles