如何使用 Persistent 启用自动记录 SQL 语句
Posted
技术标签:
【中文标题】如何使用 Persistent 启用自动记录 SQL 语句【英文标题】:How to enable automatic logging of SQL statements with Persistent 【发布时间】: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)
【问题讨论】:
【参考方案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
以上是关于如何使用 Persistent 启用自动记录 SQL 语句的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 Apache HttpClient 5 启用线路日志记录
如何使用 terraform 为自动创建的 GKE 集群和服务防火墙规则启用 Logconfig