この質問はgroundhogまたはに関するものですpersistent。どちらも同じ問題を共有していると私は信じているからです。
Tr m aいくつかの機能を提供するトランスがあるとしますf :: Int -> Tr m ()。この機能には、データベースへのアクセスが必要です。ここで使用できるオプションはいくつかありますが、満足できるものはありません。
DbPersistのどこかに変圧器を置くことができTrます。実際には、標準のトランスフォーマーのインスタンスがなく、さらにnewtypePersistBackendのインスタンスを作成する必要があるため、これを一番上に配置する必要があります。Trクラスが最小からかけ離れているため、これはすでにひどいものです。私が行うすべての db アクションを持ち上げることもできます。
もう 1 つのオプションは、 の署名を に変更するfことPersistBackend m => Int -> Tr m ()です。これもまた、私のnewtype でPersistBackendインスタンスを作成するか、リフティングする必要があります。Tr
ここからが本当の問題です。すでに制約Trがあるコンテキスト内で実行するにはどうすればよいですか? PersistBackendと共有する方法はありませんTr。
最初のオプションを実行して、いくつかの新しい接続プールDbPersist内で実際のトランスフォーマーを実行するTrことができます (私が既にいるコンテキストからプールを取得する方法がないことがわかる限りPersistBackend)、または 2 番目のオプションを実行することができます。実行関数を にしますrunTr :: PersistBackend m => Tr m a -> m a。2番目のオプションは実際には完全に問題ありませんが、ここでの問題は、DbPersist最終的にスタックのどこかになければならない が、現在トランスフォーマーの下にあり、構成されている標準トランスフォーマーのインスタンスTrがないことです。PersistBackendTr
ここで正しいアプローチは何ですか?現時点では、ReaderTリクエストに応じて接続プールを提供するスタックのどこかにセパタレrunDbConnを使用し、DB にアクセスしたいすべての場所でそのプールを使用するのが最善の選択肢のようです。DbPersist基本的にすでにそれがいかに重要であるかを見ると、ReaderTそれをしなければならないことに意味がありません。