Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Csv 在clojure中将大文件写入磁盘_Csv_Clojure - Fatal编程技术网

Csv 在clojure中将大文件写入磁盘

Csv 在clojure中将大文件写入磁盘,csv,clojure,Csv,Clojure,我有一个返回大量行的sql查询。我想将查询结果保存到磁盘上的csv文件中。但是,因为有太多的行,所以在sql查询聚合所有行之前,我的内存已经用完了 如下所示,在查询部分失败: (-> query format-transformer csv-writer) 我在clojure irc频道的帮助下找到了答案。您将需要两个库: (ns myproj.example (:require [[clojure.java.jdbc :as sql] [clojure.d

我有一个返回大量行的sql查询。我想将查询结果保存到磁盘上的csv文件中。但是,因为有太多的行,所以在sql查询聚合所有行之前,我的内存已经用完了

如下所示,在查询部分失败:

(-> query format-transformer csv-writer)

我在clojure irc频道的帮助下找到了答案。您将需要两个库:

(ns myproj.example
  (:require [[clojure.java.jdbc :as sql]
             [clojure.data.csv :as csv]]))
诀窍是处理返回的每一行,然后丢弃它。java jdbc库具有查询功能,该功能使用
:row fn
:result set fn
选项提供此功能

(defn sql->csv  [title]
  (with-open [w (clojure.java.io/writer (str title ".csv") :append true)]
   (sql/query ds (second query)
             :row-fn (fn [row]
                       (csv/write-csv w  [(mapv str (vals row))]))
             :result-set-fn dorun)))
有趣的部分是
:行fn
:结果集fn

每次从查询返回一行时,都会调度
:行fn
。每一行都是一个映射,格式为
{:column1“data”:column2“data2”}
。我们将映射更改为csv可以使用的东西(嵌套向量):
[(mapv str(:vals row)])
。然后write csv将其附加到给定的文件中

:结果集fn
对于不破坏堆至关重要。通过将其设置为
dorun
,您可以告诉它在处理头部时丢弃头部


这个特定的实现没有提供列标题,这是留给读者的一个练习(我的太令人尴尬了,无法在公共论坛上发布)。

我假设您的
:row fn
现在可以打开和关闭每一行的文件。更糟糕的是,它必须扫描到文件末尾的每一行。我还没有对它进行测试,但我认为如果在
sql/query
之外使用open调用
,这可能会更有效。我还认为,根据最新的研究,您实际上想要设置
:结果集fn
,而不是
:行集fn
。我猜
的默认
doall
:结果集fn
的作用相同,或者您使用的是旧版本。@schaueho:说得好,谢谢。我已经测试了这些更改,使用open在
中运行速度更快。我试着将
write csv
函数放入
:result set fn
,但结果返回的nils与行数一样多。