resultset-seq
返されるwith-query-results
はおそらく、あなたが得ようとしているのと同じくらい怠惰です。あなたが言ったように、怠惰はハンドルが開いている間だけ機能します。これを回避する方法はありません。データベース ハンドルが閉じている場合、データベースから読み取ることはできません。
I/O を実行し、ハンドルを閉じた後もデータを保持する必要がある場合は、ハンドルを開き、すばやく丸呑みし (怠惰を克服)、ハンドルを閉じて、後で結果を処理します。一度にすべてをメモリに保持せずに一部のデータを反復処理する場合は、ハンドルを開き、データに対して遅延 seq を取得しdoseq
てから、ハンドルを閉じます。
したがって、各行で(副作用のために)何かを行い、結果セット全体をメモリに食い込まずに結果を破棄する場合は、次のようにします。
(defn do-something-with-all-foo [f]
(let [sql "select * from foo"]
(with-connection *db*
(with-query-results res [sql]
(doseq [row res]
(f row))))))
user> (do-something-with-all-foo println)
{:id 1}
{:id 2}
{:id 3}
nil
;; transforming the data as you go
user> (do-something-with-all-foo #(println (assoc % :bar :baz)))
{:id 1, :bar :baz}
{:id 2, :bar :baz}
{:id 3, :bar :baz}
データを長期的に保持したい場合は、read-all-foo
上記の関数を使用してすべてを丸呑みすることもできます (したがって、怠惰を打ち負かします)。データを変換する場合は、map
すべてをフェッチした後に結果を調べます。その時点でデータはすべてメモリ内にmap
ありますが、呼び出し自体とフェッチ後のデータ変換は遅延します。