【问题标题】:How to enable automatic logging of SQL statements with Persistent如何使用 Persistent 启用自动记录 SQL 语句
【发布时间】:2015-05-13 12:32:32
【问题描述】:

我已经搜索了这个问题的明确答案,但还没有找到 - 如何启用对持久执行的 SQL 语句的自动日志记录?有人可以给我一个小示例程序吗?

以下是当前没有日志记录的示例程序。如何启用登录?

share [mkPersist sqlSettings, mkMigrate "migrateAll"] [persistLowerCase|
    Person
    name Text
    status Text Maybe
    deriving Show
|]

main :: IO ()
main = runSqlite ":memory:" $ do
    runMigration migrateAll
    insert (Person "Oliver Charles" Nothing)
    insert (Person "Jon Snow" Nothing)
    insert (Person "Marky Mark" (Just "helloo helloo"))
    noStatusPeople >>= mapM_ (liftIO . print)
    where
        noStatusPeople =
            select $ from $ \person -> do
                where_ (person ^. PersonStatus ==. val Nothing)
                return (person ^. PersonName)

【问题讨论】:

    标签: haskell logging persistent esqueleto


    【解决方案1】:

    您需要在实现 MonadLogger 而不仅仅是 IO 的 Monad 中调用您的 SQL 代码。 (见http://hackage.haskell.org/package/monad-logger-0.3.13.1/docs/Control-Monad-Logger.html#v:runStdoutLoggingT)。但是,runSqlite 已经为您设置了日志记录(无...),因此您需要使用较低级别的函数 withSqliteConn。 例如,如果您将代码更改为:

    import Control.Monad.Logger
    import Control.Monad.Trans.Resource
    
    runResourceT $ runStdoutLoggingT $ withSqliteConn ":memory:" . runSqlConn  $ do...
    

    (通过对资源和 monad-logger 的适当依赖),您可以将 SQL 语句写入标准输出。

    作为一个真实的例子,看看我的 scion-class-browser 项目: 在https://github.com/JPMoresmau/scion-class-browser/blob/5ab9c7576f8faf93299826e72defe70dd5b6dd6f/src/Server/PersistentCommands.hs#L93 中,您会看到对 runSqlite 的调用。 runLogging 是一个辅助函数,用于在记录或不记录之间切换,在https://github.com/JPMoresmau/scion-class-browser/blob/f7f2ab0de4f4edb01b307411abf0aa951a3c7c48/src/Scion/PersistentBrowser/DbTypes.hs#L16 中定义(当前构建版本不记录,替换为注释掉的代码)。

    当然,您可以编写自己的 MonadLogger 实现,而不是使用简单的转储到 stdout 或 stderr。

    附带说明一下,您的代码不会打印出匹配的记录,因为您不应该与 val Nothing 进行比较,而是使用 isNothing:

    where_ (isNothing $ person ^. PersonStatus)
    

    【讨论】:

    • 我可能遗漏了一些东西。我尝试输入您的代码,但似乎没有效果。以下是正确的吗? main :: IO ()main = runResourceT $ runStdoutLoggingT $ runSqlite ":memory:" $ do输出还是只有-Migrating: CREATE TABLE "person"("id" INTEGER PRIMARY KEY,"name" VARCHAR NOT NULL,"status" VARCHAR NULL)
    • 对不起,我的错误,runSqlLite 已经设置了日志记录(无),所以您需要使用较低级别的函数。我已经更新了我的答案。
    • 成功了!谢谢!是的,我意识到我应该使用isNothing,这是我在没有 SQL 日志记录的情况下花了一段时间才找到并提示这个问题的错误 :)
    • @JPMoresmau 你知道如何在 yesod 项目中做到这一点吗?看来我应该更改此行logFunc = messageLoggerSource tempFoundation appLogger
    猜你喜欢
    • 2016-05-15
    • 2015-01-19
    • 2012-01-02
    • 1970-01-01
    • 2010-09-16
    • 2018-02-18
    • 1970-01-01
    相关资源
    最近更新 更多