我正在尝试用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
密钥时,我才会遇到错误。
我在尝试不该做的事情吗?这是坏习惯吗?如有任何帮助,我们将不胜感激。
注意:我已经阅读了这个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)))
一切如预期。
这里的问题是korma.core/where
不是一个函数,需要特殊处理。Where不能作为一个函数来实现,并且仍然可以正确地处理(where query (or (= :hits 1) (> :hits 5)))
之类的事情
您可以像使用select*
一样使用where*
函数。只需将您的条款映射为:
(def clauses {:where* {:column1 10} :fields "a,b" :limit 10 :offset 500})
只是一种预感;扩展一些线程宏会让人很难判断它们是否正确:
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看起来很可疑。