Clojure:如何将JDBC4Array转换为Clojure的seq?

4

我尝试使用JDBC从数据库中查询数据。问题在于有些列是数组类型。

;get that particular column
(def jdbc-array (with-connection *db*                                                                    
                  (with-query-results rs ["select * from refgene limit 5"]                                        
                    (:exonstarts (first rs)))))

;Check if it has a value
(print jdbc-array)
;#<Jdbc4Array {67075873,67078739,67085754,67100417,67109640,67113051,67129424,67131499,67143471,67162932}>nil

;check class
(class jdbc-array)
;org.postgresql.jdbc4.Jdbc4Array

如何将这个数组转换为序列/向量在Clojure中?我尝试了(seq jdbc-array) 和(seq (.getArray jdbc-array)),但都不起作用...

后者应该可以工作,因为seq知道数组。你遇到了什么错误? - kotarak
我得到了‘nil’。看起来 getArray 返回了一个空数组。这里有 API 文档,但我不理解。http://jdbc.postgresql.org/development/privateapi/org/postgresql/jdbc4/Jdbc4Array.html。 - Tg.
Jdbc4Array实际上不是一个数组,也不支持Iterable接口。在使用seq之前,您需要先将其转换为数组或支持Iterable的对象。 - mikera
有指针吗?我对Java和Clojure都很陌生。 - Tg.
根据 java.sql.Array.getArray + seq 的组合应该可以工作。您也可以尝试 .getResultSet + resultset-seq。我怀疑 .getArray 返回一个空数组或 nil,因为 seq 没有抱怨。 - kotarak
2个回答

7

如果您觉得with-connection选项很笨重(我也是这么觉得的),您可以扩展IResultSetReadColumn协议,将Jdbc4Array对象转换为常规或向量:

以下是一种方法:

(extend-protocol clojure.java.jdbc/IResultSetReadColumn
  org.postgresql.jdbc4.Jdbc4Array
  (result-set-read-column [pgobj metadata i]
    (vec (.getArray pgobj))))

在读取时,这将把所有的数组类型转换为向量。

这种方法也可以帮助处理JSON数据类型,例如 这个例子


3

好的,我明白了。在关闭连接之前,我需要调用getArray,否则它会返回nil。

不确定为什么...我的猜测是Clojure的惰性求值。

;work
(with-connection *db*
  (with-query-results rs ["select * from refgene limit ?" 5]
    (seq (.getArray (:exonends (first rs))))))

是的,除非您完全将查询结果处理为简单值,否则您将遇到结果集的惰性。另一种解决方法是使用doall(with-query-results ...(doall(:exonends(first rs)))) - Sean Corfield

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接