首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用korma和clojure生成查询子句

使用korma和clojure生成查询子句
EN

Stack Overflow用户
提问于 2012-06-09 21:08:10
回答 3查看 1.7K关注 0票数 3

我正在尝试基于列和值的映射生成korma查询条件,并将其传递给函数。

我发现当一个空的map被传递到korma的地方时:

代码语言:javascript
复制
(select "things"
  (where conditions))

生成包含空WHERE的查询,这会导致SQL错误:

代码语言:javascript
复制
SELECT * FROM things WHERE () LIMIT 10 

但是,使用此表单:

代码语言:javascript
复制
(select "things"
  (if-not (empty? conditions) 
    (where conditions)))

导致错误:“传递给:core$where的参数数(1)错误”

korma中有没有处理动态子句的惯用方法?

更新

下面的代码行得通,但非常笨拙(请注意奇怪的必要if格式)

代码语言:javascript
复制
(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)))     
EN

回答 3

Stack Overflow用户

发布于 2012-06-09 22:16:44

我认为,如果不研究korma并尝试调用一些私有API,是否有可能生成动态查询,但这不是一个好主意。第二段代码的问题是selectwhere都是宏。select的作用是:

代码语言:javascript
复制
(defmacro select
    [ent & body]
      `(let [query# (-> (select* ~ent)
                     ~@body)]
         (exec query#)))

正如您所看到的,它将select*返回值线程到下一个表单,并且如果您引入了导致线程中断的if子句,并且where只获得一个值(这是您的映射),而不是select*的获取值和该映射,则该错误将显示错误的参数数量。

到目前为止,带一些动态代码生成功能的eval似乎是你的朋友。类似于:

代码语言:javascript
复制
(eval `(select "things"
       ~(if (empty? conditions) 
           `identity
           `(where conditions))))

我还没有试过,但我希望它能给你一些启发。

票数 3
EN

Stack Overflow用户

发布于 2012-09-20 05:15:38

一开始有点奇怪,但是牢记“代码即数据”的咒语,我创建了一个"my- where“函数,它要么传递没有条件的原始查询,要么插入一个真正的korma where子句作为结果。

类似于:

代码语言:javascript
复制
(defn my-where [query conditions]
  (if-not (nil? conditions)
    (-> query (where conditions))
    query))

然后你可以使用:

代码语言:javascript
复制
(select "things"
  (my-where conditions))

希望这能帮上忙

格雷格

票数 1
EN

Stack Overflow用户

发布于 2014-03-22 04:07:39

你可能已经想出了解决这个问题的方法,但我会加入的。就我个人而言,我最终使用的是cond->宏,如果您使用的是Clojure 1.6+,则可以使用该宏。

您可以在新的线程宏here上找到相关信息。

生成的代码如下所示:

代码语言:javascript
复制
(let [query (->(select* "things") 
                 (fields :id :data)
                 (limit 10))]
  (-> (cond-> query
         conditions (where conditions)
         more-conditions (where more-conditions))
      (exec)))
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10961285

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档