如何从clojure.java.jdbc中删除或创建数据库?

时间:2011-10-20 08:16:58

标签: postgresql clojure

我想从clojure.java.jdbc创建/删除数据库。这失败了:

(require '[clojure.java.jdbc :as sql])

(def db
  {:classname "org.postgresql.Driver"
   :subprotocol "postgresql"
   :subname "//localhost/postgres"
   :user "postgres"})

(defn drop-database [name]
  (sql/do-commands (str "drop database " name)))

(sql/with-connection db 
  (drop-database "db_name"))

因为do-commands启动了一个事务,显然你不能在事务中删除或创建数据库。有任何想法吗?

谢谢!

4 个答案:

答案 0 :(得分:5)

获取do-commandshere)的来源并移除对transaction的调用:

(defn drop-database [name]
  (sql/with-connection db
    (with-open [s (.createStatement (sql/connection))]
      (.addBatch s (str "drop database " name))
      (seq (.executeBatch s)))))

答案 1 :(得分:2)

无事务执行功能已归入db-do-commands

现在这个稍微简单的版本正在运行:

(jdbc/db-do-commands postgres-db false "CREATE DATABASE foo")

如果你没有指定false作为第二个参数,它将无法工作,因为它将尝试启动一个事务。

答案 2 :(得分:0)

对于较新的clojure版本,建议的方法不再有效。我成功完成了这个功能:

(defn exec-db-command [db command]
  (jdbc/with-db-connection [conn db]
    (with-open [s (.createStatement (:connection conn))]
      (.executeUpdate s command))))

(exec-db-command db "create database foo")

答案 3 :(得分:0)

这是唯一对我有用的解决方案

(def datasource-options {:auto-commit        true
                         :read-only          false
                         :connection-timeout 30000
                         :validation-timeout 5000
                         :idle-timeout       600000
                         :max-lifetime       1800000
                         :minimum-idle       10
                         ;; :maximum-pool-size  10
                         :pool-name          "db-pool"
                         :adapter            (:database-adapter env)
                         :username           (:database-username env)
                         :password           (:database-password env)
                         :database-name      (:database-name env)
                         :server-name        (:database-host env)
                         :port-number        (:database-port env)
                         :register-mbeans    false})

(defonce datasource
  (delay (make-datasource datasource-options)))

(defn db-jdbc-uri [& {:as args}]
  (let [datasource-options (merge datasource-options args)]
    (format "jdbc:%s://%s:%s/%s?user=%s&password=%s"
            (datasource-options :adapter) (datasource-options :server-name)
            (datasource-options :port-number) (datasource-options :database-name)
            (datasource-options :username) (datasource-options :password))))

(defn create-database [name]
  (jdbc/with-db-connection [conn {:connection-uri (db-jdbc-uri :database-name "")}]
    (jdbc/db-do-commands conn false (str "CREATE DATABASE " name) )))   

(defn drop-database [name]
  (jdbc/with-db-connection [conn {:connection-uri (db-jdbc-uri :database-name "")}]
      (jdbc/db-do-commands conn false (str "DROP DATABASE " name) )))

基本上,您需要在不提供数据库或连接到其他数据库(不是要删除的数据库)的情况下进行连接

这将翻译为该代码。

(defn create-database [name]
  (jdbc/with-db-connection [conn {:connection-uri "jdbc:postgresql://localhost/postgres?user=username&password=yourpassword"}]
    (jdbc/db-do-commands conn false (str "CREATE DATABASE " name) ))