如何使用 Persistent 启用 SQL 语句的自动记录

How to enable automatic logging of SQL statements with Persistent

我已经搜索了这个问题的明确答案,但还没有找到 - 如何启用持久性执行的 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)

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

import Control.Monad.Logger
import Control.Monad.Trans.Resource

runResourceT $ runStdoutLoggingT $ withSqliteConn ":memory:" . runSqlConn  $ do...

(对 resourcet 和 monad-logger 具有适当的依赖性),您可以将 SQL 语句写入标准输出。

举个真实的例子,看看我的 scion-class-browser 项目: 在https://github.com/JPMoresmau/scion-class-browser/blob/5ab9c7576f8faf93299826e72defe70dd5b6dd6f/src/Server/PersistentCommands.hs#L93 you see the call to runSqlite. runLogging is a helper function, to switch between logging or no logging, defined in https://github.com/JPMoresmau/scion-class-browser/blob/f7f2ab0de4f4edb01b307411abf0aa951a3c7c48/src/Scion/PersistentBrowser/DbTypes.hs#L16(当前构建版本不记录,替换为注释掉的代码)。

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

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

where_ (isNothing $ person ^. PersonStatus)