【问题标题】:Trouble connecting to postgresql DB on Heroku with Korma (Clojure)使用 Korma (Clojure) 连接到 Heroku 上的 postgresql DB 时出现问题
【发布时间】:2012-11-01 11:01:15
【问题描述】:

我在 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”,因此支持 ssl 连接到数据库。 Korma 目前不支持此功能。我将在 Github 上提交问题以允许这种连接方式。

【问题讨论】:

  • 有什么方法可以从底层数据库引擎获取错误消息 - 特别是 PgJDBC 引发的错误,如果你正在使用它? “连接被拒绝”或“没有用于...的 pg_hba.conf 条目”等
  • 我去看看克雷格。我认为 postgres.heroku 中有一个数据库日志
  • 这是日志消息 - 致命:主机“x.x.x.x”、用户“用户名”、数据库“dbname”、SSL 关闭没有 pg_hba.conf 条目
  • 嗯。在非 Heroku 设置中这很简单,但我知道 Heroku 如何管理 pg_hba.conf。不过,也许这会让你开始寻找一些东西。
  • 据我发现,这似乎是在没有 SSL 的情况下连接的问题。但是我没有发现关于 Korma 上的 SSL 连接的任何信息!

标签: postgresql heroku clojure korma


【解决方案1】:

编辑: 没有理由再使用[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 和他们的连接池配置示例,所以它可能不太适合每个人的需求,而且这只是一个hack。理想情况下,原始 Korma 项目应该集成这些更改或其他可能的解决方案。

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

【讨论】:

【解决方案2】:

其实解决方案非常简单,只在本地工作:

(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"]

【讨论】:

  • (or port 80)?为什么不(or port 5432)
【解决方案3】:

在您的编辑中,您提到切换到 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"})

【讨论】:

    【解决方案4】:

    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)))})
    

    【讨论】:

    • 感谢您的回答我尝试了您的代码,不幸的是它没有工作。我对错别字进行了一些编辑,例如。第 6 行 - “def db”现在是“defdb dbname”。我一直在工作,直到我建立了连接,我得到了同样的错误。 :(
    • 是否可以选择向 Korma 或底层 JDBC 添加 SSL 连接?啊,这现在很令人沮丧。除了这个,我已经准备好整个应用程序了。
    猜你喜欢
    • 2013-07-17
    • 2013-03-28
    • 1970-01-01
    • 2014-03-28
    • 1970-01-01
    • 2013-11-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多