使用Clojure在数据库上循环

Mic*_*hel 1 database postgresql clojure heroku heroku-postgres

我刚刚开始ClojureHeroku,首先阅读此介绍.现在处于弄脏手的阶段,我正面临着在循环中处理数据库的这个问题.

这是有效的:

(for 
  [s (db/query (env :database-url)
                   ["select * from My_List"])]
      ; here one can do something with s, for example:
      ; print out (:field s)
)
Run Code Online (Sandbox Code Playgroud)

但是,根据需要更新循环内的变量是不够的.阅读这个主题,我理解Clojure有自己的处理变量的方法我需要使用循环模式.

这是我尝试过的:

(loop [a 0 b 1
       s (db/query (env :database-url)
                 ["select * from My_List"])]
      ; here I want to do something with s, for example
      ; print out (:field s)
      ; and do the following ... but it does not work!
  (if (> (:otherField s) 5)
    (:otherField s)
    (recur (+ a (:otherField s)) b s))
)
Run Code Online (Sandbox Code Playgroud)

由于我在写这篇文章之前尝试了各种方法,我知道上面的代码工作,除了我在数据库方面做错了.

所以这就是我的问题:我需要做些什么才能让它发挥作用?

Mat*_*mer 6

我知道,当你习惯于不同的范式时,最初很难进入功能性思维.

我不认为有关"如何正确执行此循环"的正确解释,因为在此处执行循环是不对的.

对我来说最不正确的两件事:

  1. 永远不要做SELECT * FROM table.这不是关系数据库的使用方式.例如,当您想要所有值的总和大于5时,您应该:SELECT SUM(field) FROM my_list WHERE field > 5

  2. 不要在循环中思考(如何做),而是在想要对数据做什么:

    • 我想在字段上工作:otherFIeld
    • 我只对大于5的值感兴趣
    • 我想要所有剩余值的总和

然后你来到这样的事情:

(reduce +
        (filter #(> % 5)
                (map :otherField
                     (db/query (env :database-url) ["select * from My_List"]))))
Run Code Online (Sandbox Code Playgroud)

(根本没有循环.)