在Persistent(Haskell)中,如何仅在记录尚不存在的情况下才能插入记录?

时间:2018-04-01 15:05:15

标签: haskell haskell-persistent

我是Haskell初学者,所以请提前道歉!

我一直关注the Persistent tutorial here

我有一个具有唯一性约束的数据模型:

Book
    gutId Int
    UniqueGutId gutId
    ...
    author [AuthorId]
    ... 
Author
    gutId Int
    UniqueAuthorGutId gutId
    ...

当我使用以下内容转到insert时:

  runSqlite "test.db" $ do
    runMigration migrateAll

    -- FIXME: This won't work if there's an author that's already in the database.
    authorIds <- mapM insert authors

如果记录已在数据库中,则无效。 (它只会返回异常。)我可以这样做:

authorIds <- mapM insertUnique authors

但问题是,我需要稍后使用authorIds更新Book条记录。所以我只是想知道是否有人知道一个简单的方法来插入一个记录,如果它不存在,并返回新的密钥,或获取记录密钥,如果它已经存在,所以我有一个键数组的方式。 The full code at this point is up here.

2 个答案:

答案 0 :(得分:1)

您只需执行自己提到的两项操作:

authorIds <- forM authors $ \a -> do
    res <- insertUnique a
    case res of
        Just key -> return key
        _ -> fromJust <$> getBy (authorGutId a)

答案 1 :(得分:0)

怎么样

authorIds <- mapM (fmap (either entityKey id) . insertBy) authors

insertBy :: _ => -- some constraints
            record -> -- given some record, try to insert it
            _ ( -- in some monad
               Either (Entity record) (Key record)
               -- if found: Left existing
               -- otherwise: Right newKey
              )
Data.Either.either :: (l -> o) -> (r -> o) -> Either l r -> o
-- eliminator for Either
-- purpose and implementation completely determined by type

我们使用insertBy尝试插入记录。 fmap在monad下方进行演练,either entityKey id提取Key