【发布时间】:2016-08-28 16:38:21
【问题描述】:
这个问题是关于groundhog 或persistent,因为我相信两者都有同样的问题。
假设我有一个变压器Tr m a,它提供了一些功能f :: Int -> Tr m ()。此功能需要数据库访问。我可以在这里使用几个选项,但没有一个是令人满意的。
我可以在Tr 内部的某处放置一个DbPersist 变压器。实际上,我需要把它放在顶部,因为标准转换器没有PersistBackend 实例,而且我仍然需要为我的Tr newtype 编写一个实例。这已经很糟糕了,因为课程远非最小。我还可以解除我所做的每一个数据库操作。
另一个选项是将f 的签名更改为PersistBackend m => Int -> Tr m ()。这将再次需要我的Tr newtype 上的PersistBackend 实例,或者提升。
现在真正的问题来了。如何在已经具有PersistBackend 约束的上下文中运行Tr?无法与Tr 分享。
我可以选择第一个选项并使用一些新的连接池在Tr 内运行实际的DbPersist 转换器(据我所知,没有办法从PersistBackend 上下文中获取池我' m 已经在),或者我可以执行第二个选项并将运行函数设置为runTr :: PersistBackend m => Tr m a -> m a。第二个选项实际上完全没问题,但这里的问题是 DbPersist,最终必须在堆栈中的某个位置,现在位于 Tr 转换器下,并且没有标准的 PersistBackend 实例由Tr 组成的变压器。
这里的正确方法是什么?目前似乎最好的选择是在堆栈中的某个地方使用一个单独的ReaderT,它可以根据请求为我提供连接池,然后在我想访问数据库的任何地方使用该池进行runDbConn。看到DbPersist 基本上已经只是一个ReaderT 我不明白必须这样做的意义。
【问题讨论】:
标签: database haskell monad-transformers haskell-persistent