我在Heroku的配置设置中解析postgresql uri。但我似乎无法让它发挥作用。任何帮助将不胜感激,我可能会错过一些直接的东西。
以下是使用的代码。
(def dev-db-info
{:db "dbname"
:user "username"})
(defn parse-db-uri
[uri]
(drop 1 (split uri #"://|:|@|/")))
(defn create-map-from-uri
[uri]
(let [parsed (parse-db-uri uri)]
(zipmap [:user :password :host :port :db] parsed)))
(defn db-info
[]
(if production?
(create-map-from-uri (System/getenv "DATABASE_URL"))
dev-db-info))
(defdb connected-db
(postgres (db-info)))
我从uri检索的地图如下所示:
{:db "dbname"
:port "5662"
:host "ec2-url.compute-1.amazonaws.com"
:password "pwd"
:user "username"}
我收到以下错误:
Connections could not be acquired from the underlying database!
编辑:
我已经放弃使用Korma,并转而使用Clojure.JDBC 0.2.3,它支持“connection-uri”,因此支持与db的ssl连接。 Korma目前不支持这一点。我将在Github上提交一个问题以允许这种连接方法。
答案 0 :(得分:5)
编辑:
没有理由再使用[org.clojars.ccfontes/korma "0.3.0-beta12-pgssl"]
了。阅读this以了解更多相关信息。另外,请忽略以下说明。
添加了postgres SSL支持。
在project.clj
插入:
[org.clojars.ccfontes/korma "0.3.0-beta12-pgssl"]
在heroku上定义与postgres数据库的连接:
(ns app.db
(:require [clojure.java.jdbc :as sql]
[korma.db :as db]
[clojure.string :as string])
(:import (java.net URI)))
(defn set-app-pg-db! [mode]
(let [db-uri (java.net.URI. (System/getenv "DATABASE_URL"))]
(->> (string/split (.getUserInfo db-uri) #":")
(#(identity {:db (last (string/split (System/getenv "DATABASE_URL") #"\/"))
:host (.getHost db-uri)
:port (.getPort db-uri)
:user (% 0)
:password (% 1)
:ssl true
:sslfactory (when (= mode :dev) "org.postgresql.ssl.NonValidatingFactory")}))
(db/postgres)
(db/defdb app-pg-db))))
该修补程序使用Tomcat JDBC Connection Pool及其配置示例作为连接池,因此它可能不太适合每个人的需求,而且这只是一个黑客攻击。理想情况下,原始的Korma项目应该整合这些变化或其他可能的解决方案。
非常感谢来自其他人的一些反馈,因为它仅在我自己的项目中进行过测试。感谢。
答案 1 :(得分:1)
实际上解决方案非常简单,只能在本地运行:
(defn- convert-db-uri [db-uri]
(let [[_ user password host port db] (re-matches #"postgres://(?:(.+):(.*)@)?([^:]+)(?::(\d+))?/(.+)" db-uri)]
{
:user user
:password password
:host host
:port (or port 80)
:db db
}))
(def db-spec (postgres
(convert-db-uri
(config/get "DATABASE_URL"))))
其中DATABASE_URL是“postgres:// user:pw @ host:port / dbname?ssl = true& sslfactory = org.postgresql.ssl.NonValidatingFactory”
似乎db名称将SSL参数转发给底层驱动程序,它只是起作用。
这是:
[korma "0.3.0-beta9"]
[org.clojure/java.jdbc "0.1.3"]
[postgresql/postgresql "9.1-901.jdbc4"]
答案 2 :(得分:1)
在您的编辑中,您提到切换到clojure.java.jdbc,因为它允许您使用连接URI启用SSL。您可以使用korma使用korma.db / defdb函数使用相同的技术,它允许您提供自己的连接URL并使用如下查询字符串启用SSL:
(defdb korma-db {:classname "org.postgresql.Driver"
:subprotocol "postgresql"
:subname "//localhost:5432/test?ssl=true"
:user "my-username"
:password "my-password"})
答案 3 :(得分:0)
FWIW,这是我用来从Heroku的DATABASE_URL
得到一个clojure.java.jdbc db-spec(我认为是Korma想要的)的代码。
(def db-uri (java.net.URI. (System/getenv "DATABASE_URL")))
(def user-and-password (clojure.string/split (.getUserInfo db-uri) #":"))
(def db
{:classname "org.postgresql.Driver"
:subprotocol "postgresql"
:user (get user-and-password 0)
:password (get user-and-password 1) ; may be nil
:subname (if (= -1 (.getPort db-uri))
(format "//%s%s" (.getHost db-uri) (.getPath db-uri))
(format "//%s:%s%s" (.getHost db-uri) (.getPort db-uri) (.getPath db-uri)))})