Variable behavior for .onConflict[X] method of .insert?

Let's say that I create an array of insert statements along the lines of db.insert(targetTable).values(targetValues) and, on a conflict, I want different behavior based on why there was a conflict. For instance, if the conflict arises due to the id field having a unique constraint that would be violated by the entry, I would want to update, like: db.insert(targetTable).values(targetValues).onConflictDoUpdate({ target: targetTable.id, set: targetValues }) However, if a different field of the insert has a unique violation, I’d want to do nothing like: db.insert(targetTable).values(targetValues).onConflictDoNothing({ target: targetTable.anotherUniqueField }) And a third field has a foreign key constraint that would be violated by the insert. I would imagine that would look like: db.insert(targetTable).values(targetValues).onConflictDoNothing({ target: targetTable.fieldWForeignConstraint }) What I’d REALLY like to be able to do is something of my choosing on a conflict like logging the skipped entry to a file. Something like: db.insert(targetTable).values(targetValues).onConflict((conflictObject) => { if(conflictObject.field === “id”){ conflictObject.update({ target: targetTable.id, set: targetValues }) } if(conflictObject.field === “anotherUniqueField” { // write to file here console.log("this entry was skipped do to a conflict on the field: "anotherUniqueField", targetValues); // do nothing return; } if(conflictObject.field === “fieldWForeignConstraint” { // write to file here console.log("this entry was skipped do to a conflict on the field: “fieldWForeignCosntraint”", targetValues); // do nothing return; } }) Is anything like this possible? Can the .onConflict[X] methods be chained maybe? I’ve found that the Drizzle documentation doesn’t have a very thorough description of the API or the methods’ arguments, etc. so I have a hard time knowing what is and isn’t possible with the package.
5 Replies
Case S.
Case S.OP2mo ago
Does anyone happen to have any insight into whether what I'm trying to accomplish is possible or not within the library as it currently exists?
alexblokh
alexblokh2mo ago
hey, yeah, we've investigated and it does seem onConflict statements were implemented non fully compliant with SQL and we will update it in the next release https://github.com/drizzle-team/drizzle-orm/pull/4028
GitHub
SQLite onConflict chaining fix by Sukairo-02 · Pull Request #4028 ·...
Fixed SQLite onConflict clauses being overwritten instead of stacked added related tests removed unused import
Case S.
Case S.OP5w ago
@alexblokh That's great! Two questions: 1. Is there documentation/examples showing how to chain and how it behaves? 2. Is there a way to do custom behavior inside an onConflict method? Something like in my question where I create a log entry before performing the onConflict behavior?
alexblokh
alexblokh4w ago
it now behaves exactly like SQL would be, every onConflict clause just appends this clause to sql statement and you can examine this statement in every query via .toSQL there's also no extra onConflict business logic apart from one in sql

Did you find this page helpful?