8

我在 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 上提交一个问题以允许这种连接方法。

4

4 回答 4

5

编辑:没有理由再使用[org.clojars.ccfontes/korma "0.3.0-beta12-pgssl"]了。阅读本文以了解更多信息。另外,请忽略以下说明。

添加了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 连接池及其连接池的配置示例,因此它可能不太适合每个人的需求,而且这只是一个 hack。理想情况下,原始 Korma 项目应该集成这些更改或其他可能的解决方案。

感谢其他人的一些反馈,因为它只在我自己的项目中进行了测试。谢谢。

于 2012-11-30T04:21:47.950 回答
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”

似乎数据库名称将 SSL 参数转发到底层驱动程序并且它可以正常工作。

这是与:

[korma "0.3.0-beta9"]
[org.clojure/java.jdbc "0.1.3"]
[postgresql/postgresql "9.1-901.jdbc4"]
于 2013-01-31T12:31:49.333 回答
1

在您的编辑中,您提到切换到 clojure.java.jdbc 因为它允许您使用连接 URI 启用 SSL。您可以使用函数 korma.db/defdb 对 Korma 使用相同的技术,该函数允许您提供自己的连接 URL 并使用如下查询字符串启用 SSL:

(defdb korma-db {:classname "org.postgresql.Driver"
                 :subprotocol "postgresql"
                 :subname "//localhost:5432/test?ssl=true"
                 :user "my-username"
                 :password "my-password"})
于 2013-04-03T22:35:02.367 回答
0

FWIW,这是我用来从 Heroku 的DATABASE_URL.

(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)))})
于 2012-11-02T15:07:04.673 回答