metabase / toucan

A classy high-level Clojure library for defining application models and retrieving them from a DB
Eclipse Public License 1.0
570 stars 49 forks source link

Toucan put a string as table name in sql using mysql #72

Open rascio opened 4 years ago

rascio commented 4 years ago

Hi @camsaul,
I'm playing with Toucan, connecting to a mysql db. I configured Toucan to work with hikari datasource and mount:

(ns reviews.database
  (:require [hikari-cp.core :as h]
            [mount.core :refer [defstate]]
            [toucan.models :refer [set-root-namespace!]]
            [toucan.db :refer [set-default-db-connection!]]))

;move to configuration
(def datasource-options {:auto-commit        true
                         :read-only          false
                         :connection-timeout 30000
                         :validation-timeout 5000
                         :idle-timeout       600000
                         :max-lifetime       1800000
                         :minimum-idle       1
                         :maximum-pool-size  10
                         :pool-name          "db-pool"
                         :adapter            "mysql"
                         :username           "root"
                         :password           "root"
                         :database-name      "reviews-app"
                         :server-name        "localhost"
                         :port-number        3306
                         :register-mbeans    false})

(defn- create-datasource []
    (doto {:datasource (h/make-datasource datasource-options)}
          (set-default-db-connection!)))

(defstate database 
    :start (create-datasource)
    :stop (h/close-datasource (database :datasource)))

(set-root-namespace! 'reviews.models)

Having my model:

(ns reviews.models.review
    (:require [toucan.models :refer [defmodel]]))

(defmodel Review :reviews)

When I do:

user=> (t/debug-print-queries 
         (t/select 'Review))
;output
; {:select [:*],
;  :from [{:table :reviews, :name "Review", :toucan.models/model true}]}
; nil 
; SELECT *
; FROM "reviews"
; null

I get the following exception:

Execution error (MySQLSyntaxErrorException) at
jdk.internal.reflect.NativeConstructorAccessorImpl/newInstance0 (NativeConstructorAccessorImpl.java:-2).

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '"reviews"' at line 1 class com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException

The issue is that it writes the table name as "reviews" instead of review.
Have I misconfigured something or is this some sort of bug?

lucywang000 commented 4 years ago

Have you tried to change this

(defmodel Review :reviews)

to

(defmodel Review :review)
gazz commented 4 years ago

I ran into the same issue. You have to set default quoting style: (toucan.db/set-default-quoting-style! :mysql) or bind toucan.db/*quoting-style* dynamic var. it is documented here: https://github.com/metabase/toucan/blob/master/docs/setup.md#configuring-quoting-style