【问题标题】:Missing FROM-clause entry for table?缺少表的 FROM 子句条目?
【发布时间】:2018-04-17 11:08:42
【问题描述】:

当我从具有多个关系的表中选择特定字段时,我会收到如下异常:org.postgresql.util.PSQLException: ERROR: missing FROM-clause entry for table \"bar\"

这是我定义的关系:

(declare foo bar)

(korma/defentity foo
                 (korma/pk :token)
                 (korma/database db)
                 (korma/table :foo)
                 (korma/has-many bar {:fk :token}))

(korma/defentity bar
                 (korma/pk :token)
                 (korma/database db)
                 (korma/table :bar)
                 (korma/belongs-to foo {:fk :token}))

这是我在 sqlkorma 中生成的查询:

(defn fetch []
  (->
    (korma/select* foo)
    (korma/with bar)
    (korma/fields :foo.token :bar.col)
    (korma/exec)))

如果我选择使用 * 的所有字段,则查询运行没有问题。但是,我想指定我要选择哪些字段,我做错了什么?

【问题讨论】:

    标签: clojure sqlkorma


    【解决方案1】:

    我放弃了与 Korma 合作的尝试。我认为使用基本的 SQL 互操作可能会更好:

    (ns tst.demo.jdbc
      (:use demo.core tupelo.core tupelo.test)
      (:require
        [clojure.java.jdbc :as jdbc]
        [clojure.string :as str]
        [clojure.java.io :as io] ))
    
    (def db {:classname   "org.h2.Driver"
             :subprotocol "h2:mem"
            ;:subname     "./korma.db"
             :subname     "demo;DB_CLOSE_DELAY=-1" ; -1 very important!!!
                              ; http://www.h2database.com/html/features.html#in_memory_databases
                              ; http://makble.com/using-h2-in-memory-database-in-clojure
             :user "sa"
             :password ""
             })
    
    (dotest
      (spyx (jdbc/db-do-commands db ["drop table if exists langs"]))
      (spyx (jdbc/db-do-commands db ["drop table if exists releases"]))
      (spy :create
           (jdbc/db-do-commands
             db
             (jdbc/create-table-ddl :langs
                                    [[:id :serial]
                                     [:lang "varchar not null"]])))
      (spy :create
           (jdbc/db-do-commands
             db
             (jdbc/create-table-ddl :releases
                                    [[:id :serial]
                                     [:desc "varchar not null"]
                                     [:langId "numeric"]])))
      (spy :insert
           (jdbc/insert-multi! db :langs
                               [{:lang "Clojure"}
                                {:lang "Java"}]))
      ;; -> ({:lang "Clojure", :id 1} {:lang "Java", :id 2})
      (spyx-pretty (jdbc/query db ["select * from langs"]))
    
      (let [clj-id (grab :id (only (jdbc/query db ["select id from langs where lang='Clojure'"])))]
        (spyx clj-id)
        (spy :insert-rel
             (jdbc/insert-multi! db :releases
                                 [{:desc "ancients" :langId clj-id}
                                  {:desc "1.8" :langId clj-id}
                                  {:desc "1.9" :langId clj-id}])) )
      (let [java-id (grab :id (only (jdbc/query db ["select id from langs where lang='Java'"])))]
        (spyx java-id)
        (spy :insert-rel
             (jdbc/insert-multi! db :releases
                                 [{:desc "dusty" :langId java-id}
                                  {:desc "8" :langId java-id}
                                  {:desc "9" :langId java-id}
                                  {:desc "10" :langId java-id}])) )
      (spyx-pretty
       (jdbc/query db [
       "select langs.lang, releases.desc
           from langs inner join releases
           on (langs.id = releases.langId)
           where lang = 'Clojure' "]) )
      )
    

    结果:

    (jdbc/db-do-commands db ["drop table if exists langs"]) => (0)
    (jdbc/db-do-commands db ["drop table if exists releases"]) => (0)
    :create => (0)
    :create => (0)
    :insert => ({:id 1} {:id 2})
    (jdbc/query db ["select * from langs"]) =>
    ({:id 1, :lang "Clojure"} {:id 2, :lang "Java"})
    clj-id => 1
    :insert-rel => ({:id 1} {:id 2} {:id 3})
    java-id => 2
    :insert-rel => ({:id 4} {:id 5} {:id 6} {:id 7})
    (jdbc/query db ["select langs.lang, releases.desc\n       from langs inner join releases\n       on (langs.id = releases.langId)\n       where lang = 'Clojure' "]) =>
    ({:lang "Clojure", :desc "ancients"}
     {:lang "Clojure", :desc "1.8"}
     {:lang "Clojure", :desc "1.9"})
    

    【讨论】:

    • 这似乎无法解决我的问题。
    【解决方案2】:

    想想,我在错误的地方传递了bar.col 字段。我想因为这是一个多方关系,sql korma 必须离开并在这里运行 n+1 查询。这解释了为什么我会看到 missing FROM-clause 异常,因为我告诉 sql korma 获取错误查询中的字段。

    (defn fetch []
      (->
        (korma/select* foo)
        (korma/fields :token)
        (korma/with bar (korma/fields :col))
        (korma/exec)))
    

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-04-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多