You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Clojure用java.jdbc执行PostgreSQL Upsert遇参数数量错误求助

Fixing the ArityException in clojure.java.jdbc Batch Upsert

Let's break down your problem first: that ArityException is happening because you're passing 4 arguments to sql/execute!, but the 0.6.1 version of clojure.java.jdbc only accepts up to 3 arguments (the connection spec, the SQL/params structure, and optional config options). Your current code is passing the parameter list as a separate third argument, which doesn't align with the API's expected signature.

Here are two corrected approaches to get your batch upsert working:

Approach 1: Embed parameter groups in the SQL vector

You can combine your SQL string with all parameter groups into a single vector, then pass the :multi? true option to trigger batch processing:

;; For users table
(when (pos? (count updatesU))
  (sql/execute! spec 
                (into ["insert into users(id, name) values (?, ?) on conflict(id) do update set name=EXCLUDED.name;"]
                      updatesU)
                {:multi? true}))

;; For time_entries table
(when (pos? (count updatesTE))
  (sql/execute! spec 
                (into ["insert into time_entries(id, spent_date, hours, userid, project, task) values (?, ?, ?, ?, ?, ?) on conflict(id) do update set spent_date=EXCLUDED.spent_date, hours=EXCLUDED.hours;"]
                      updatesTE)
                {:multi? true}))

Approach 2: Use a map to separate SQL and parameters

This is a cleaner approach if you prefer to keep SQL and params distinct. Pass a map with :sql and :params keys, then add the batch config:

;; For users table
(when (pos? (count updatesU))
  (sql/execute! spec 
                {:sql "insert into users(id, name) values (?, ?) on conflict(id) do update set name=EXCLUDED.name;"
                 :params updatesU}
                {:multi? true}))

;; For time_entries table
(when (pos? (count updatesTE))
  (sql/execute! spec 
                {:sql "insert into time_entries(id, spent_date, hours, userid, project, task) values (?, ?, ?, ?, ?, ?) on conflict(id) do update set spent_date=EXCLUDED.spent_date, hours=EXCLUDED.hours;"
                 :params updatesTE}
                {:multi? true}))

A quick note: I swapped your if for when since you don't have an else branch—this makes the code more idiomatic Clojure.

The :multi? true flag tells execute! to treat each element in your updatesU/updatesTE lists as a separate set of parameters for the upsert query, which is exactly what you need for batch operations.

内容的提问来源于stack exchange,提问作者supernova

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 09:07:05