Пример MongoDB для Yesod/Persistent

Новичок в Haskell и Yesod. Я пытался следовать примеру интеграции с Yesod из главы Persistent в книге Yesod (http://www.yesodweb.com/book/persistent). Кажется, что Sqlite компилируется и работает нормально. Тем не менее, я пытаюсь использовать MongDB, и мне трудно заставить все работать. Конкретно:

  1. В примере для sqlite:

    share [mkPersist sqlSettings, mkMigrate "migrateAll"] [persist|

    В книге Yesod говорится: «Вместо этого код Mongo будет использовать mongoSettings». Но я не могу найти его ни в одном из модулей, и код не компилируется. Поэтому вместо mongoSettings мне пришлось использовать это:

    MkPersistSettings { mpsBackend = ConT ''Action }

    Мне пришлось импортировать Language.Haskell.TH.Syntax, чтобы его скомпилировать, что, как я предполагаю, должно быть скрыто от пользователя, поэтому я определенно делаю это неправильно.

    Кроме того, я обнаружил, что в тестах Persistent для Mongo обходятся без части «поделиться» и «мигрировать». Я на самом деле не уверен, почему, я предполагаю, что это потому, что MongoDB не содержит схемы и не нуждается в миграции?

  2. SqlPersist

    Я думал, что MongoPersist будет аналогом SqlPersist, и я думаю, что это почти так — я нашел один экземпляр MongoPersist в init.hs в тестовом каталоге Persistent. Но это закомментировано, поэтому у меня есть ощущение, что оно устарело? В противном случае, насколько я могу судить, он все равно не определен. Поэтому я не знаю, как преобразовать следующую строку (стр. 115 книги Йесод или ближе к концу http://www.yesodweb.com/book/persistent) для работы с MongoDB:

    instance YesodPersist PersistTest where
        type YesodPersistBackend PersistTest = SqlPersist
        runDB action = do
            PersistTest pool <- getYesod
            runSqlPool action pool
    
  3. Использование с MongoDBConn

    Итак, для sqlite код (1-й пример с веб-страницы выше):

    main :: IO ()
    main = withSqliteConn ":memory:" $ runSqlConn $ do
        runMigration migrateAll
        johnId <- insert $ Person "John Doe" $ Just 35
        ... and so on
    

    Но

    main :: IO()
    main = withMongoDBConn ":memory:" $ runMongoDBConn $ do
        runMigration migrateAll 
        johnId <- insert $ Person "John Doe" $ Just 35
        ... and so on          
    

не работает. Во-первых, runMigration по какой-то причине не входит в область действия. Хорошо, может быть, мне не нужна миграция для MongoDB, поэтому я удаляю эту строку. Затем компилятор жалуется: Couldn't match expected typeAccessMode' с фактическим типом m0 b0' Expected type: m0 t0 -> (t0 -> m0 b0) -> AccessMode Actual type: m0 t0 -> (t0 -> m0 b0) -> m0 b0 и так далее. И на этом этапе моего очень поверхностного знания монад просто недостаточно, чтобы понять это.

В общем, мне очень трудно преобразовать пример интеграции с Yesod из книги из Sqlite в MongoDB. Может ли кто-нибудь предоставить мне конкретный пример Yesod/Persistent с MongoDB? Большое спасибо заранее.


person Victor    schedule 31.07.2012    source источник
comment
Вы можете использовать инструмент формирования шаблонов yesod init, создать сайт MongoDB и посмотреть, как он настроен. Трудно точно сказать, каких частей не хватает в том, как вы объяснили свою ситуацию.   -  person dflemstr    schedule 31.07.2012
comment
Спасибо за предложение. Просмотр этого немного помогает ... хотя по большей части результирующий код в дереве каталогов слишком сложен для меня, чтобы понять, что происходит. Я отредактирую исходный пост, чтобы прояснить ситуацию.   -  person Victor    schedule 31.07.2012


Ответы (2)


Сегодня я добавил страницу в кулинарную книгу Github Yesod, которая использует MongoDB в сочетании с Persistent. Однако он не использует withMongoDBConn и не избегает TH. Кроме того, я объясняю, почему я использую отдельный файл конфигурации YAML. Ссылка: http://bit.ly/VLvmoK

person Obscaenvs    schedule 17.12.2012
comment
Этот пример должен быть исправлен для последней версии persist-mongodb 2.x: let mongoSettings = (mkPersistSettings (ConT ''MongoContext)) {mpsGeneric = False} - person The_Ghost; 24.01.2016
comment
MongoBackend изменен с помощью MongoContext - person The_Ghost; 24.01.2016

Я знаю, что это ответ на старый вопрос, но вот независимый от Yesod способ заставить Persistent работать с MongoDB. Это может быть полезно для других новичков в Persistent.

{-# LANGUAGE TemplateHaskell #-}

import Database.Persist 
import Database.Persist.TH
import Database.Persist.MongoDB
import Network (PortID (PortNumber))

let mongoSettings = (mkPersistSettings (ConT ''MongoBackend)) {mpsGeneric = False}
    in share [mkPersist mongoSettings] [persistLowerCase|
Person
    name String
    age Int Maybe
    deriving Show
BlogPost
    title String
    authorId PersonId
    deriving Show
|]
runDBActions actions = 
    withMongoDBConn "myDatabaseName" "localhost" (PortNumber 27017) Nothing 2000 $ \pool ->    
        runMongoDBPool master actions pool

actions = do
    mkey <- insert $ Person "John Doe" $ Just 35
    ...

main :: IO ()
main = do
    runDBactions actions
person iamnat    schedule 30.05.2014