Macros Clojure Korma:无法运行聚合计数
我正在尝试使用Clojure+Korma运行一个简单的查询来提取记录数。 这就是我想做的:Macros Clojure Korma:无法运行聚合计数,macros,clojure,korma,Macros,Clojure,Korma,我正在尝试使用Clojure+Korma运行一个简单的查询来提取记录数。 这就是我想做的: (defmacro number-of [ref & filter] `(let [basetmp# (-> (kc/select* ~ref) (kc/aggregate (count :*) :cnt))] (if ~filter (-> basetmp# (kc/where ~filte
(defmacro number-of [ref & filter]
`(let [basetmp# (-> (kc/select* ~ref)
(kc/aggregate (count :*) :cnt))]
(if ~filter
(-> basetmp#
(kc/where ~filter))
basetmp#)))
但是,如果我尝试使用此宏,则会收到一条错误消息,提示:
传递给以下对象的参数数目错误:核心$count
如果在函数中执行该查询,则该查询将非常有效,但存在一些错误/缺失
在宏中,我无法发现:(
谢谢,
尼科正如庞佐所指出的,你的计数是错误的 看看宏观扩张
(number-of 'foo) ;; expands to....
(clojure.core/let [basetmp__9167__auto__ (clojure.core/->
(korma.core/select* 'foo)
(korma.core/aggregate
(clojure.core/count :*)
:cnt))]
(if nil
(clojure.core/-> basetmp__9167__auto__ (korma.core/where nil))
basetmp__9167__auto__))
因此,您需要防止宏中的计数被扩展为clojure.core/count
,您可以使用unquote/quote这样做:
(defmacro number-of [ref & filter]
`(let [basetmp# (-> (kc/select* ~ref)
(kc/aggregate (~'count :*) :cnt))]
(if ~filter
(-> basetmp#
(kc/where ~filter))
basetmp#)))
然后会像预期的那样扩展
(clojure.core/let [basetmp__9137__auto__ (clojure.core/->
(korma.core/select* 'foo)
(korma.core/aggregate
(count :*)
:cnt))]
(if nil
(clojure.core/-> basetmp__9137__auto__ (korma.core/where nil))
basetmp__9137__auto__))
结果SQL看起来合理:
(kc/as-sql (number-of 'foo))
"SELECT COUNT(*) \"cnt\" FROM \"foo\""
更新:从评论“计数实际代表什么?”-如果您意识到
kc/aggregate
也是一个宏,并且参数是某种类型的“SQL aggregate”DSL,那么您也可以展开kc/aggregate
调用。您会发现有一个函数,parse aggregate
,它最终映射到korma.SQL.fn/agg count
:
(clojure.core/let [q__2640__auto__ (kc/select* 'foo)]
(korma.sql.engine/bind-query
q__2640__auto__
(clojure.core/let [res__2641__auto__ (korma.core/fields
q__2640__auto__
[(clojure.core/->
q__2640__auto__
(korma.sql.fns/agg-count
:*))
:cnt])]
(if nil
(korma.core/group res__2641__auto__ nil)
res__2641__auto__))))
正如ponzao所指出的,你的计数是错误的 看看宏观扩张
(number-of 'foo) ;; expands to....
(clojure.core/let [basetmp__9167__auto__ (clojure.core/->
(korma.core/select* 'foo)
(korma.core/aggregate
(clojure.core/count :*)
:cnt))]
(if nil
(clojure.core/-> basetmp__9167__auto__ (korma.core/where nil))
basetmp__9167__auto__))
因此,您需要防止宏中的计数被扩展为clojure.core/count
,您可以使用unquote/quote这样做:
(defmacro number-of [ref & filter]
`(let [basetmp# (-> (kc/select* ~ref)
(kc/aggregate (~'count :*) :cnt))]
(if ~filter
(-> basetmp#
(kc/where ~filter))
basetmp#)))
然后会像预期的那样扩展
(clojure.core/let [basetmp__9137__auto__ (clojure.core/->
(korma.core/select* 'foo)
(korma.core/aggregate
(count :*)
:cnt))]
(if nil
(clojure.core/-> basetmp__9137__auto__ (korma.core/where nil))
basetmp__9137__auto__))
结果SQL看起来合理:
(kc/as-sql (number-of 'foo))
"SELECT COUNT(*) \"cnt\" FROM \"foo\""
更新:从评论“计数实际代表什么?”-如果您意识到
kc/aggregate
也是一个宏,并且参数是某种类型的“SQL aggregate”DSL,那么您也可以展开kc/aggregate
调用。您会发现有一个函数,parse aggregate
,它最终映射到korma.SQL.fn/agg count
:
(clojure.core/let [q__2640__auto__ (kc/select* 'foo)]
(korma.sql.engine/bind-query
q__2640__auto__
(clojure.core/let [res__2641__auto__ (korma.core/fields
q__2640__auto__
[(clojure.core/->
q__2640__auto__
(korma.sql.fns/agg-count
:*))
:cnt])]
(if nil
(korma.core/group res__2641__auto__ nil)
res__2641__auto__))))
我认为你的
count
是clojure.core/count
而不是Korma的count函数。我认为你的count
是clojure.core/count
而不是Korma的count函数。谢谢你sw1nn。这确实有效,尽管我不完全理解这里的~'的行为。你做了什么(count:*)实际上表示?为什么在评估阶段不执行函数count?我添加了一些关于什么(count:*)
representsThank you!!现在我明白了。我确实看过聚合的实现,但现在才明白(count)函数并没有真正得到评估,但在编译时被宏替换为agg count!!我应该更仔细地阅读代码;)谢谢sw1nn。尽管我不完全理解~'在这里的行为,但这确实有效。(count:*)实际上代表什么?为什么函数count不能在eval阶段执行?我添加了一些关于什么的进一步说明(count:*)
表示感谢!!现在我明白了。实际上,我看过aggregate的实现,但直到现在我才明白,(count)函数并没有真正得到评估,而是在编译时被宏替换为agg count!!我应该更仔细地阅读代码;)