2

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

我一直在这里关注 Persistent 教程

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

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记录。所以我只是想知道是否有人知道一种简单的方法来插入一条记录,如果它不存在,并返回新键,或者如果它已经存在则获取记录键,这样我就有一个键数组. 此时的完整代码在此处。

4

2 回答 2

1

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

authorIds <- forM authors $ \a -> do
    res <- insertUnique a
    case res of
        Just key -> return key
        _ -> fromJust <$> getBy (authorGutId a)
于 2018-04-01T16:06:49.350 回答
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.

于 2018-04-01T16:12:43.270 回答