Support upsert with empty updates#301
Conversation
|
Ah, dang. In the event that we do an So the most proper type of At least, as a default. Playing around locally, the following form works: WITH inserted AS (
INSERT INTO "OneUnique" (name, value)
VALUES ("asdf", 0)
ON CONFLICT (value)
DO NOTHING
RETURNING id, name, value
)
SELECT id, name, value
FROM inserted
UNION
SELECT id, name, value
FROM "OneUnique"
WHERE value = 0But I have no idea what sorts of performance this has. This StackOverflow question/answer has some details and it looks to be somewhat complicated. Maybe the type of coolUpsert entity updates =
case NonEmpty.nonEmpty updates of
Just nonEmptyUpdates ->
Just <$> upsert entity nonEmptyUpdates
Nothing ->
insertOnConflictDoNothing entityIt might be tempting to write: But this only means that the uniqueness key is the same, not the rest of the values. |
parsonsmatt
left a comment
There was a problem hiding this comment.
Dang, this is more complicated than I thought.
| import Common.Test.Import hiding (from, on) | ||
| import PostgreSQL.MigrateJSON | ||
|
|
||
| spec :: Spec |
There was a problem hiding this comment.
this is just moved up to the top
| testUpsert :: SpecDb | ||
| testUpsert = | ||
| describe "Upsert test" $ do | ||
| testUpsert = describe "Upsert test" $ do |
There was a problem hiding this comment.
fixed formatting to be 4 space indent
test/PostgreSQL/Test.hs
Outdated
| itDb "Works with no updates" $ do | ||
| _ <- EP.upsert u1 [] | ||
| pure () |
There was a problem hiding this comment.
New test case here
| itDb "Works with no updates" $ do | ||
| _ <- EP.upsert u1 [] | ||
| pure () |
There was a problem hiding this comment.
Well, this passes. Hooray.
test/PostgreSQL/Test.hs
Outdated
| itDb "Works with no updates, twice" $ do | ||
| Entity u1Key u1' <- EP.upsert u1 [] | ||
| Entity u1Key_ u1'' <- EP.upsert u1 { oneUniqueName = "Something Else" } [] | ||
| pure () |
There was a problem hiding this comment.
Unfortunately, this fails with ErrorCall "head: empty list".
The reason is that:
INSERT INTO "OneUnique" (name, value)
VALUES (?, ?)
ON CONFLICT DO NOTHING
RETURNING id, name, valuedoes not return anything if we don't perform an INSERT - so the return is [] which he head on and it goes boom.
DO UPDATE always does something. But we really don't want to do something silly like DO UPDATE SET blah = EXCLUDED.blah because this does unnecessary writes and triggers.
* Remove `Coercible` abiilty for `SqlExpr`. (#413) * Remove Coercible * Remove coercible * update docs and changelog * Support upsert with empty updates (#301) * Support upsert with empty updates * stylish, changelog link * clean * remove focus * oh no * update with new api * tests pass * Fix distinctOn (#287) * Fix distinctOn * lol * expose * Deprecation Cycles for 3.6 (#412) * Deprecate ilike outside of Postgres * lol * Deprecation Cycling * wow okay cool * oh woops * Add fixity on question-dot operator (#420) * Add fixity on question-dot operator * changelog link * Deprecate LockingKind constructors (#421) * Deprecate LockingKind constructors * changelog * `HasField` for `SqlExpr (Maybe (Entity a))` joins `Maybe` (#422) * HasField on SqlExpr (Maybe Entity) joins Maybe * hmmm that works kinda nicely * Incorporate changes from the work codebase * add another test case * changelog * wat * wat * wat * 3.6 fixups (#425) * Re-export Nullable from ToMaybe * Fixity on ilike * lolwhoops * changelog link * add toBaseIdMaybe and fromBaseIdMaybe * start sketching out the sqlcoerce class * no sqlcoerce yet * ok for convenience
Fixes #300
Before submitting your PR, check that you've:
@sincedeclarations to the Haddock.stylish-haskelland otherwise adhered to the style guide.After submitting your PR: