【问题标题】:Entering relations to database using Persistent使用 Persistent 输入与数据库的关系
【发布时间】:2015-09-09 18:49:13
【问题描述】:

从 Haskell 和 Yesod 开始,相对于 Haskell,Yesod 可能有点过分了:)

我使用 Persistent via 构建实体

share [mkPersist sqlSettings, mkMigrate "migrateAll"][persistLowerCase|
Game
  title String
  company String
  UniqueTitle title
  deriving Show
Tag
  label String
  description String Maybe
  UniqueLabel label
  deriving Show
GameTag
  gameId GameId
  tagId TagId
  UniqueGameTag gameId tagId
|]

-- Yesod related code ...

我主要有

main :: IO ()
main = do
let taggings = fromFile :: [(Game, Tag)] -- fromFile code not included
runStderrLoggingT $ withSqlitePool ":inmemory:" 10 $ λpool →  liftIO $ do
runResourceT $ flip runSqlPool pool $ do
  runMigration migrateAll
  let (g, t) = head taggings
  gid ←  insert g
  tid ←  insert t
  insert (GameTag gid tid)
warp 3000 $ App pool

这样做,我将第一个关系放入数据库,通过从列表中选择元素,我可以“手动”添加更多元素,但我无法弄清楚如何通过以某种方式迭代将所有关系放入数据库taggings。如何定义一个可以映射到taggings ::[(Game, Tag)] 的函数并插入构造的GameTag 类型的游戏标签 由持久?

【问题讨论】:

    标签: haskell yesod persistent


    【解决方案1】:

    这里的主要技巧不是拉出函数,这很简单:

    f (g, t) = do
      gid <- insert g
      tid <- insert t
      insert (GameTag gid tid)
    

    诀窍是知道如何使用它....标准map 不能单独工作,因为该函数是在 monad 中定义的(你可以使用它,它只会给你一个动作列表,而无需运行它们)。

    map f taggings -- returns just a list, type [ResourceT IO a], doesn't run anything
    

    这里有两种从 main 中实际运行操作的方法。

    sequence (map f taggings) --sequentially runs the actions in the list
    

    或者,更易读

    forM taggings f
    

    或者,稍微详细一点

    forM taggings $ \tagging -> do
      f tagging
    

    您可能还想查看mapM。还应该了解forM_sequence_ 以抑制(通常是无用的)返回值。

    【讨论】:

      猜你喜欢
      • 2016-06-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-22
      • 2011-05-08
      • 1970-01-01
      • 2017-01-26
      • 2017-03-19
      相关资源
      最近更新 更多