[WIP] Refactor upsert, repsert, upsertBy and create repsertBy#785
[WIP] Refactor upsert, repsert, upsertBy and create repsertBy#785pythonissam wants to merge 11 commits intoyesodweb:masterfrom
Conversation
|
issue ref: #782 |
|
I would suggest that the amount of description you have added here is better suited to a blog post, rather than to reference material like Haddocks. In particular, duplicating the boilerplate Person definitions for every method is distracting. (It's also unworkable: mkPersist will create a Person data type.) |
|
I think your understanding of upsert is not yet complete. :) The upsert methods are only usable on entities that have specified uniqueness constraints. Entities with uniqueness constraints might cause Repsert, on the other hand.... Looking at the documentation, repsert is not what I thought it was. It looks like it must have been based on Mongo's idea of repsert. I had assumed it was a member of PersistUniqueWrite, just like upsert. In my universe, repsert has type And it replaces on conflict, rather that updates on conflict. This is what MySQL's replace command does. I guess I should add a method Hope that helps. |
|
I'm definitely in favor of keeping the example documentation. However, it would be better to move the duplicate parts to the top of There are also some slight modifications we could make to make the example documentation a little shorter |
|
@chreekat @MaxGabriel However, As both of you said, added examples seem to have room for improvement... |
8a5a4fb to
ff0db5c
Compare
|
@chreekat @MaxGabriel I've updated and fixed the examples of @chreekat Also, I've implemented |
I'll leave it to your judgment. |
| -- We try to explain 'upsertBy' using the schema 2. | ||
| -- | ||
| -- @ | ||
| -- upsertBy (UniqueUserName \"SPJ\") (Person \"X\" 999) [PersonAge +=. 15] |
There was a problem hiding this comment.
If you'd like, you can use the "bird track" haddock code syntax, so you don't have to escape things:
> upsertBy (UniqueUserName "SPJ") (Person "X" 999) [PersonAge +=. 15]
The main advantage to the @ syntax is that you can create hyperlinks to identifiers using single quotes, but if you aren't doing that then it's noisier to use @
|
|
|
@MaxGabriel Thank you!! and I'm gonna fix haddock later as you suggested:) |
|
@naushadh I've implemented
Is this alright? Considering its name, I think it should map repsertMany
:: (MonadIO m, PersistRecordBackend record backend)
=> [(Key record, record)] -> ReaderT backend m ()
repsertMany = mapM_ (uncurry repsert)but in the repsertMany krs = do
let es = (uncurry Entity) `fmap` krs
let ks = entityKey `fmap` es
let mEs = Map.fromList $ zip ks es
mRsExisting <- getMany ks
let mEsNew = Map.difference mEs mRsExisting
let esNew = snd `fmap` Map.toList mEsNew
insertEntityMany esNew |
|
Another question. upsert
:: (MonadIO m, PersistRecordBackend record backend)
=> record -- ^ new record to insert
-> [Update record] -- ^ updates to perform if the record already exists (leaving
-- this empty is the equivalent of performing a 'repsert' on a
-- unique key)
-> ReaderT backend m (Entity record) -- ^ the record in the database after the operation
repsert :: (MonadIO m, PersistRecordBackend record backend)
=> Key record -> record -> ReaderT backend m ()Is there any reason for leaving it like this? I think it'll be more convenient if |
|
@MaxGabriel Yet the implementation isn't finished, I guess my work is mostly done. For now, would you review my commits and correct my English accordingly? |
| -- | Replace based on a uniqueness constraint or insert: | ||
| -- | ||
| -- * insert the new record if it does not exist; | ||
| -- * If the record exists (matched via it's uniqueness constraint), then replace the existing record with the given record. |
| -- Batch version of 'repsertUnique' for SQL backends. | ||
| -- | ||
| -- Useful when migrating data from one entity to another | ||
| -- and want to preserve ids. |
There was a problem hiding this comment.
Useful when migrating data from one entity to another and want to preserve ids.
This should have a subject for the verb want, something like:
Useful when you're migrating from one entity to another and want to preserve IDs.
|
@pythonissam Ok what do you think about this: we don't add |
|
@pythonissam: |
|
@MaxGabriel No problem with that, except |
|
@naushadh Hmm... I understand, but it isn't the batch version of repsert, is it? I suggest that we change the name of it to clarify what it actually does. |
|
@pythonissam What's wrong with repsert that it should be changed? |
|
@MaxGabriel It's a matter of correspondence:
It's like "Why is there |
|
@MaxGabriel So we won't add any new functions for now, right? |
|
ping @MaxGabriel @naushadh |
1 similar comment
|
ping @MaxGabriel @naushadh |
|
I was surprised to see this pull request after making a pull request #804 . I have no malice. However, apparently, in this pull request, it seems that repsertBy has not been created yet. |
|
@ncaq Never mind. However, actually, I did it. Please look at this commit. Let me explain my thoughts. Firstly, -- https://github.com/yesodweb/persistent/blob/master/persistent/Database/Persist/Class/PersistUnique.hs#L99-L112
upsertBy :: Unique record -> record -> [Update record] -> ReaderT backend m (Entity record)gets Secondly, -- https://github.com/yesodweb/persistent/blob/master/persistent/Database/Persist/Class/PersistUnique.hs#L79-L94
upsert :: record -> [Update record] -> ReaderT backend m (Entity record)-- https://github.com/yesodweb/persistent/blob/master/persistent/Database/Persist/Class/PersistStore.hs#L204-L208
repsert :: Key record -> record -> ReaderT backend m ()for some reason, -- https://github.com/yesodweb/persistent/pull/785/commits/67534d0d4f93792bb3209ac28c8ac4729661c927
repsertUnique :: record -> ReaderT backend m ()and implemented its By version: repsertUniqueBy :: Unique record -> record -> ReaderT backend m () |
|
To sum up the discussion: If we re-implement repsert* functions
If we don't
What should I do to merge this PR? It would be helpful if you show me a rough guideline. |
|
@pythonissam insertBy :: (MonadIO m, PersistUniqueWrite backend, PersistRecordBackend record backend) => record -> ReaderT backend m (Either (Entity record) (Key record)) I do not think that |
|
@ncaq Furthermore, I guess |
unique type mean is that type of arguments have
I forgot two uniqueness pattern. case |
|
Since There's been no progress recently, I'm thinking of closing this PR... How do you think? |
|
I haven't worked with these functions myself, so I'm not qualified to give a useful opinion, sorry. |
|
@pythonissam I had to root around a bit to answer the question for myself, but I don't think repsert/upsert (the non-By variants) are a good idea. Then addressing repsert specifically, it was not obvious from the name that repsert was an upsert that doesn't return the record. The idiom for this in Haskell is to make actions that return I apologize this wasn't brought to some sort of conclusion sooner and I hope you'll continue kicking Persistent around. I'll close this PR as not accepted, if anyone feels strongly about this issue/feature please speak up. |
|
@bitemyapp |
My TODO:
repsertUniquerepsertUniqueByrepsertUniqueManyrepsertUniqueManyByBefore submitting your PR, check that you've:
@sincedeclarations to the HaddockAfter submitting your PR: