honeysql merge-在哪里构建一个大型查询

时间:2016-05-15 00:55:40

标签: clojure honeysql

我正在尝试使用honeysql以编程方式构建查询,并在我添加where子句时添加。

来自python并使用sqlalchemy,我可以做类似的事情:

In [3]: query = model.Account.query
In [4]: query = query.filter_by(id=1)
In [5]: query = query.filter_by(email='abc@foo.com')
In [6]: query = query.filter_by(username='someuser')
In [7]: query = query.filter_by(is_active=1)
In [8]: printquery(query)

SELECT *
FROM account
WHERE account.id = 1 AND account.email = 'abc@foo.com' 
      AND account.username = 'someuser' AND account.is_active = 1

但是,使用honeysql,我的where子句不是那么干净。

user=> (require '[honeysql.core :as sql])
user=> (require '[honeysql.helpers :refer :all])
user=> (->
  #_=>   (select :*)
  #_=>   (from :test)
  #_=>   (merge-where [:= :a 1])
  #_=>   (merge-where [:= :b 2])
  #_=>   (merge-where [:= :c 3])
  #_=>   (merge-where [:= :d 4])
  #_=>   sql/format)

["SELECT * FROM test WHERE (((a = 1 AND b = 2) AND c = 3) AND d = 4)"]

我知道它们在逻辑上是相同的,但随着我开始变得越来越复杂,我开始变得紧张,我会得到一些微妙的查询表现怪异的额外的parens导致我问题。

我疯了吗?我应该不再担心并且学会爱上额外的parens(毕竟这是clojure)?或者是否有更好的查询构建模式我不知道?我应该将where子句构建为一个大向量,并将它们全部添加到最后的查询映射中吗?

非常感谢任何建议!

1 个答案:

答案 0 :(得分:0)

从逻辑角度看待它

a AND b AND c = ( a AND b ) AND c = a AND ( b AND c ).

其中a,b和c是

这样的命题
A = 1

AND运算符是关联的,这意味着只要命题的序列保持不变,括号的位置或者多少都无关紧要。

制定了示例here.