我正在尝试基于列和值的映射生成korma查询条件,并将其传递给函数。
我发现当一个空的map被传递到korma的地方时:
(select "things"
(where conditions))生成包含空WHERE的查询,这会导致SQL错误:
SELECT * FROM things WHERE () LIMIT 10 但是,使用此表单:
(select "things"
(if-not (empty? conditions)
(where conditions)))导致错误:“传递给:core$where的参数数(1)错误”
korma中有没有处理动态子句的惯用方法?
更新
下面的代码行得通,但非常笨拙(请注意奇怪的必要if格式)
(defn do-select []
(-> (select* "things")
(fields :id :data)
(limit 10)))
(defn add-constraints [query conditions]
(if (empty? conditions)
query
(where query (conditions-to-clause-map conditions))))
(select (do-select)
(add-constraints conditions)
(where (is_owner? owner))) 发布于 2012-06-09 22:16:44
我认为,如果不研究korma并尝试调用一些私有API,是否有可能生成动态查询,但这不是一个好主意。第二段代码的问题是select和where都是宏。select的作用是:
(defmacro select
[ent & body]
`(let [query# (-> (select* ~ent)
~@body)]
(exec query#)))正如您所看到的,它将select*返回值线程到下一个表单,并且如果您引入了导致线程中断的if子句,并且where只获得一个值(这是您的映射),而不是select*的获取值和该映射,则该错误将显示错误的参数数量。
到目前为止,带一些动态代码生成功能的eval似乎是你的朋友。类似于:
(eval `(select "things"
~(if (empty? conditions)
`identity
`(where conditions))))我还没有试过,但我希望它能给你一些启发。
发布于 2012-09-20 05:15:38
一开始有点奇怪,但是牢记“代码即数据”的咒语,我创建了一个"my- where“函数,它要么传递没有条件的原始查询,要么插入一个真正的korma where子句作为结果。
类似于:
(defn my-where [query conditions]
(if-not (nil? conditions)
(-> query (where conditions))
query))然后你可以使用:
(select "things"
(my-where conditions))希望这能帮上忙
格雷格
发布于 2014-03-22 04:07:39
你可能已经想出了解决这个问题的方法,但我会加入的。就我个人而言,我最终使用的是cond->宏,如果您使用的是Clojure 1.6+,则可以使用该宏。
您可以在新的线程宏here上找到相关信息。
生成的代码如下所示:
(let [query (->(select* "things")
(fields :id :data)
(limit 10))]
(-> (cond-> query
conditions (where conditions)
more-conditions (where more-conditions))
(exec)))https://stackoverflow.com/questions/10961285
复制相似问题