在 Persistent (Haskell) 中,如何插入不存在的记录?
In Persistent (Haskell), how can I insert a record only if it doesn't already exist?
我是 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
如果该记录已经在数据库中,则无法使用。 (这只是 return 一个例外。)我可以这样做:
authorIds <- mapM insertUnique authors
但问题是,我稍后需要使用authorIds
来更新Book
记录。所以我只是想知道是否有人知道一种简单的方法来插入记录(如果它不存在)和 return 新密钥,或者如果它已经存在则获取记录密钥,以便我有一个数组无论哪种方式的钥匙。 The full code at this point is up here.
您只需执行您自己提到的两个操作:
authorIds <- forM authors $ \a -> do
res <- insertUnique a
case res of
Just key -> return key
_ -> fromJust <$> getBy (authorGutId a)
怎么样
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
.
我是 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
如果该记录已经在数据库中,则无法使用。 (这只是 return 一个例外。)我可以这样做:
authorIds <- mapM insertUnique authors
但问题是,我稍后需要使用authorIds
来更新Book
记录。所以我只是想知道是否有人知道一种简单的方法来插入记录(如果它不存在)和 return 新密钥,或者如果它已经存在则获取记录密钥,以便我有一个数组无论哪种方式的钥匙。 The full code at this point is up here.
您只需执行您自己提到的两个操作:
authorIds <- forM authors $ \a -> do
res <- insertUnique a
case res of
Just key -> return key
_ -> fromJust <$> getBy (authorGutId a)
怎么样
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
.