clojure:使用korma动态组合查询

clojure:使用korma动态组合查询,clojure,korma,Clojure,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]]

我正在尝试使用创建一个非常简单的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)
用法

(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子句外,所有操作均按预期进行。我可以以我选择的任何方式组合限制、偏移和字段,并得到预期的结果。只有当我有一个
:我的地图中的
键时,我才会遇到错误

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

注意:我已经读过了

编辑:从
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)))

一切正常。

只是一种预感;展开一些线程宏会使您很难看到它们是否正确:

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看起来可疑

这里的问题是
korma.core/where
不是一个函数,需要专门处理。Where不能作为函数实现,并且仍然能够正确地处理类似于
(Where查询(或(=:hits 1)(>:hits 5))
您可以在使用
时使用
Where*
函数。 只需将您的子句映射如下:

(def clauses {:where* {:column1 10} :fields "a,b" :limit 10 :offset 500})

名称和符号的价值从何而来?@ArthurUlfeldt请看我对你答案的评论。谢谢你看这个
func
是此时的关键字。一个例子是
(symbol(name:where))
,它在
korma.core
命名空间中得到解析。我只是在查找一个korma函数,这样我就可以执行它了。我认为这是可行的,它避免了算术问题,但给我留下了SQL语法问题。谢谢你的帮助。