2

我正在尝试使用korma创建一个非常简单的 API

用户可以像这样查询数据库:

localhost:8080/my_postgres_db/users.json?where[age]=50&limit=1  

目前,我在尝试将 where 子句应用于现有的可组合查询时遇到错误。

clojure.lang.ArityException: Wrong number of args (2) passed to: core$where

有问题的代码

(defn- comp-query [q [func arg]]
  (let [sql-fn (ns-resolve 'korma.core (-> func name symbol))]
    (sql-fn q arg)))

(defn compose-query [table col]
  (reduce comp-query (select* table) col))

用法

 (def clauses {:where {:column1 10} :fields "a,b" :limit 10 :offset 500})
 (-> (compose-query table clauses) select)

一切都按预期运行,除了 where 子句。我可以以我选择的任何方式组合限制、偏移和字段,并获得预期的结果。只有当我的:where地图中有钥匙时,我才会遇到错误。

我是否在尝试我不应该做的事情?这是坏的clojure吗?任何帮助,将不胜感激。

注意:我已阅读此 SO问题

编辑:从lein repl我可以以相同的方式手动编写查询并且它可以工作

(where (select* "my_table") {:a 5})

编辑: 如果我将我的compose-query功能修改为:

(defn compose-query [table col]
  ; remove where clause to process seperately
  (let [base (reduce comp-query (select* table) (dissoc col :where))]
    (if-let [where-clause (:where col)]
      (-> base (where where-clause))
      base)))

一切都按预期工作。

4

3 回答 3

3

这里的问题是它korma.core/where不是一个函数,需要特殊处理。哪里不能作为一个函数实现并且仍然可以正确处理诸如(where query (or (= :hits 1) (> :hits 5)))

于 2012-08-21T07:30:02.293 回答
3

您可以在使用时使用where*功能select*。只需将您的子句映射如下:

(def clauses {:where* {:column1 10} :fields "a,b" :limit 10 :offset 500})
于 2012-08-21T09:34:47.210 回答
1

只是一种预感; 扩展一些线程宏使得很难看出它们是否正确:

core> (macroexpand-1 '(-> (compose-query table clauses) select))
(select (compose-query table clauses))                                                                     
core> (macroexpand-1 '(-> func name symbol))
(clojure.core/-> (clojure.core/-> func name) symbol)                                                       
core> (macroexpand-1 '(clojure.core/-> func name))
(name func)

将 func 传递给 name 看起来很可疑。

于 2012-08-21T00:14:27.470 回答