diff --git a/src/metabase/api/activity.clj b/src/metabase/api/activity.clj
index 721cb03ceafa9668afe9054d8df014ebde8d946f..054653acf5bf98d012e44be31ccdb94410014b2c 100644
--- a/src/metabase/api/activity.clj
+++ b/src/metabase/api/activity.clj
@@ -25,7 +25,6 @@
 (defendpoint GET "/recent_views"
   "Get the list of 15 things the current user has been viewing most recently."
   []
-  ;; use a custom Korma query because we are doing some groupings and aggregations
   ;; expected output of the query is a single row per unique model viewed by the current user
   ;; including a `:max_ts` which has the most recent view timestamp of the item and `:cnt` which has total views
   ;; and we order the results by most recently viewed then hydrate the basic details of the model
diff --git a/src/metabase/cmd/load_from_h2.clj b/src/metabase/cmd/load_from_h2.clj
index 327002d2c59b306f4f988fef9ab662f34b4de24f..72d0b1406fe38ecfad005b05327bab84e83c7d0f 100644
--- a/src/metabase/cmd/load_from_h2.clj
+++ b/src/metabase/cmd/load_from_h2.clj
@@ -91,7 +91,7 @@
     (print (color/blue \.))
     (flush)
     (k/insert e (k/values (if (= e DashboardCard)
-                            ;; mini-HACK to fix korma/h2 lowercasing these couple attributes
+                            ;; mini-HACK to fix h2 lowercasing these couple attributes
                             ;; luckily this is the only place in our schema where we have camel case names
                             (mapv #(set/rename-keys % {:sizex :sizeX, :sizey :sizeY}) chunk)
                             chunk))))
diff --git a/src/metabase/db.clj b/src/metabase/db.clj
index e340d24d04f1869b4f2a9318185f9664e73b601e..dda0074c133a4c842cca01c4338baf721edc5c5d 100644
--- a/src/metabase/db.clj
+++ b/src/metabase/db.clj
@@ -8,11 +8,11 @@
             (honeysql [core :as hsql]
                       [format :as hformat]
                       [helpers :as h])
-            (korma [core :as k]
-                   [db :as kdb])
+            [korma.db :as kdb]
             [medley.core :as m]
             [ring.util.codec :as codec]
             [metabase.config :as config]
+            [metabase.db.spec :as dbspec]
             [metabase.models.interface :as models]
             [metabase.util :as u]
             metabase.util.honeysql-extensions) ; this needs to be loaded so the `:h2` quoting style gets added
@@ -87,15 +87,15 @@
                           :password (config/config-str :mb-db-pass)}))))
 
 (defn jdbc-details
-  "Takes our own MB details map and formats them properly for connection details for Korma / JDBC."
+  "Takes our own MB details map and formats them properly for connection details for JDBC."
   [db-details]
   {:pre [(map? db-details)]}
   ;; TODO: it's probably a good idea to put some more validation here and be really strict about what's in `db-details`
   (case (:type db-details)
-    :h2       (kdb/h2       (assoc db-details :naming {:keys   s/lower-case
-                                                       :fields s/upper-case}))
-    :mysql    (kdb/mysql    (assoc db-details :db (:dbname db-details)))
-    :postgres (kdb/postgres (assoc db-details :db (:dbname db-details)))))
+    :h2       (dbspec/h2       (assoc db-details :naming {:keys   s/lower-case
+                                                          :fields s/upper-case}))
+    :mysql    (dbspec/mysql    (assoc db-details :db (:dbname db-details)))
+    :postgres (dbspec/postgres (assoc db-details :db (:dbname db-details)))))
 
 
 ;; ## MIGRATE
@@ -188,7 +188,7 @@
       (throw (java.lang.Exception. "Database requires manual upgrade."))))
   (log/info "Database Migrations Current ... ✅")
 
-  ;; Establish our 'default' Korma DB Connection
+  ;; Establish our 'default' DB Connection
   (kdb/default-connection (kdb/create-db (jdbc-details db-details)))
 
   ;; Do any custom code-based migrations now that the db structure is up to date
@@ -269,7 +269,7 @@
 
 (def ^:private ^:dynamic *call-count*
   "Atom used as a counter for DB calls when enabled.
-   This number isn't *perfectly* accurate, only mostly; DB calls made directly to JDBC or via old korma patterns won't be logged."
+   This number isn't *perfectly* accurate, only mostly; DB calls made directly to JDBC won't be logged."
   nil)
 
 (defn do-with-call-counting
diff --git a/src/metabase/db/spec.clj b/src/metabase/db/spec.clj
new file mode 100644
index 0000000000000000000000000000000000000000..0df8b032fef678076b5b7868f2a7c263451cd951
--- /dev/null
+++ b/src/metabase/db/spec.clj
@@ -0,0 +1,65 @@
+(ns metabase.db.spec
+  "Functions for creating JDBC DB specs for a given engine.")
+
+(defn postgres
+  "Create a database specification for a postgres database. Opts should include
+  keys for :db, :user, and :password. You can also optionally set host and
+  port."
+  [{:keys [host port db make-pool?]
+    :or {host "localhost", port 5432, db "", make-pool? true}
+    :as opts}]
+  (merge {:classname "org.postgresql.Driver" ; must be in classpath
+          :subprotocol "postgresql"
+          :subname (str "//" host ":" port "/" db)
+          :make-pool? make-pool?}
+         (dissoc opts :host :port :db)))
+
+(defn mysql
+  "Create a database specification for a mysql database. Opts should include keys
+  for :db, :user, and :password. You can also optionally set host and port.
+  Delimiters are automatically set to \"`\"."
+  [{:keys [host port db make-pool?]
+    :or {host "localhost", port 3306, db "", make-pool? true}
+    :as opts}]
+  (merge {:classname "com.mysql.jdbc.Driver" ; must be in classpath
+          :subprotocol "mysql"
+          :subname (str "//" host ":" port "/" db)
+          :delimiters "`"
+          :make-pool? make-pool?}
+         (dissoc opts :host :port :db)))
+
+(defn mssql
+  "Create a database specification for a mssql database. Opts should include keys
+  for :db, :user, and :password. You can also optionally set host and port."
+  [{:keys [user password db host port make-pool?]
+    :or {user "dbuser", password "dbpassword", db "", host "localhost", port 1433, make-pool? true}
+    :as opts}]
+  (merge {:classname "com.microsoft.sqlserver.jdbc.SQLServerDriver" ; must be in classpath
+          :subprotocol "sqlserver"
+          :subname (str "//" host ":" port ";database=" db ";user=" user ";password=" password)
+          :make-pool? make-pool?}
+         (dissoc opts :host :port :db)))
+
+(defn sqlite3
+  "Create a database specification for a SQLite3 database. Opts should include a
+  key for :db which is the path to the database file."
+  [{:keys [db make-pool?]
+    :or {db "sqlite.db", make-pool? true}
+    :as opts}]
+  (merge {:classname "org.sqlite.JDBC" ; must be in classpath
+          :subprotocol "sqlite"
+          :subname db
+          :make-pool? make-pool?}
+         (dissoc opts :db)))
+
+(defn h2
+  "Create a database specification for a h2 database. Opts should include a key
+  for :db which is the path to the database file."
+  [{:keys [db make-pool?]
+    :or {db "h2.db", make-pool? true}
+    :as opts}]
+  (merge {:classname "org.h2.Driver" ; must be in classpath
+          :subprotocol "h2"
+          :subname db
+          :make-pool? make-pool?}
+         (dissoc opts :db)))
diff --git a/src/metabase/driver/bigquery.clj b/src/metabase/driver/bigquery.clj
index 86cdbc18188c62a54909f078caa89f94013326ba..1e39ed334c1c0f257086e751c8e99536c2b51eeb 100644
--- a/src/metabase/driver/bigquery.clj
+++ b/src/metabase/driver/bigquery.clj
@@ -5,10 +5,9 @@
             [clojure.tools.logging :as log]
             (honeysql [core :as hsql]
                       [helpers :as h])
-            [korma.db :as kdb]
-            (metabase [config :as config]
-                      [db :as db]
-                      [driver :as driver])
+            [metabase.config :as config]
+            [metabase.db :as db]
+            [metabase.driver :as driver]
             [metabase.driver.generic-sql :as sql]
             [metabase.driver.generic-sql.query-processor :as sqlqp]
             (metabase.models [database :refer [Database]]
diff --git a/src/metabase/driver/generic_sql.clj b/src/metabase/driver/generic_sql.clj
index 9124430ac176b81c78022de3b860bd86c5829d3f..7e327b4853162e278456e9d81b4c45c03504ce10 100644
--- a/src/metabase/driver/generic_sql.clj
+++ b/src/metabase/driver/generic_sql.clj
@@ -53,10 +53,10 @@
     "Given a `Database` DETAILS-MAP, return a JDBC connection spec.")
 
   (current-datetime-fn [this]
-    "*OPTIONAL*. Korma form that should be used to get the current `DATETIME` (or equivalent). Defaults to `:%now`.")
+    "*OPTIONAL*. HoneySQL form that should be used to get the current `DATETIME` (or equivalent). Defaults to `:%now`.")
 
   (date [this, ^Keyword unit, field-or-value]
-    "Return a korma form for truncating a date or timestamp field or value to a given resolution, or extracting a date component.")
+    "Return a HoneySQL form for truncating a date or timestamp field or value to a given resolution, or extracting a date component.")
 
   (excluded-schemas ^java.util.Set [this]
     "*OPTIONAL*. Set of string names of schemas to skip syncing tables from.")
@@ -73,9 +73,9 @@
      Return `nil` to prevent FIELD from being aliased.")
 
   (prepare-value [this, ^Value value]
-    "*OPTIONAL*. Prepare a value (e.g. a `String` or `Integer`) that will be used in a korma form. By default, this returns VALUE's `:value` as-is, which
+    "*OPTIONAL*. Prepare a value (e.g. a `String` or `Integer`) that will be used in a HoneySQL form. By default, this returns VALUE's `:value` as-is, which
      is eventually passed as a parameter in a prepared statement. Drivers such as BigQuery that don't support prepared statements can skip this
-     behavior by returning a korma `raw` form instead, or other drivers can perform custom type conversion as appropriate.")
+     behavior by returning a HoneySQL `raw` form instead, or other drivers can perform custom type conversion as appropriate.")
 
   (quote-style ^clojure.lang.Keyword [this]
     "*OPTIONAL*. Return the quoting style that should be used by [HoneySQL](https://github.com/jkk/honeysql) when building a SQL statement.
@@ -99,7 +99,7 @@
       (hsql/call :length (hx/cast :VARCHAR field-key))")
 
   (unix-timestamp->timestamp [this, field-or-value, ^Keyword seconds-or-milliseconds]
-    "Return a korma form appropriate for converting a Unix timestamp integer field or value to an proper SQL `Timestamp`.
+    "Return a HoneySQL form appropriate for converting a Unix timestamp integer field or value to an proper SQL `Timestamp`.
      SECONDS-OR-MILLISECONDS refers to the resolution of the int in question and with be either `:seconds` or `:milliseconds`."))
 
 
@@ -159,7 +159,7 @@
 
 
 (defn escape-field-name
-  "Escape dots in a field name so Korma doesn't get confused and separate them. Returns a keyword."
+  "Escape dots in a field name so HoneySQL doesn't get confused and separate them. Returns a keyword."
   ^clojure.lang.Keyword [k]
   (keyword (hx/escape-dots (name k))))
 
@@ -439,7 +439,7 @@
 
 
 (defn- db->korma-db
-  "Return a Korma DB spec for Metabase DATABASE."
+  "Return a DB spec for Metabase DATABASE."
   [{:keys [details engine], :as database}]
   (let [spec (connection-details->spec (driver/engine->driver engine) details)]
     (assoc (create-db spec)
@@ -453,7 +453,7 @@
                                                (name (hx/escape-dots (name s))))))))
 
 (defn korma-entity
-  "Return a Korma entity for [DB and] TABLE.
+  "Return a entity for [DB and] TABLE.
 
     (-> (Table :id 100)
         korma-entity
diff --git a/src/metabase/driver/h2.clj b/src/metabase/driver/h2.clj
index e5ab944ffd27ba3617558e58911227488c538bc2..05112669c25144fca60ce2542d31859c755cd17e 100644
--- a/src/metabase/driver/h2.clj
+++ b/src/metabase/driver/h2.clj
@@ -2,8 +2,8 @@
   ;; TODO - This namespace should be reworked to use `u/drop-first-arg` like newer drivers
   (:require [clojure.string :as s]
             [honeysql.core :as hsql]
-            [korma.db :as kdb]
             [metabase.db :as db]
+            [metabase.db.spec :as dbspec]
             [metabase.driver :as driver]
             [metabase.driver.generic-sql :as sql]
             [metabase.util :as u]
@@ -104,8 +104,8 @@
                                                           "ACCESS_MODE_DATA" "r"}))))
 
 (defn- connection-details->spec [_ details]
-  (kdb/h2 (if db/*allow-potentailly-unsafe-connections* details
-              (update details :db connection-string-set-safe-options))))
+  (dbspec/h2 (if db/*allow-potentailly-unsafe-connections* details
+                 (update details :db connection-string-set-safe-options))))
 
 
 (defn- unix-timestamp->timestamp [_ expr seconds-or-milliseconds]
diff --git a/src/metabase/driver/mysql.clj b/src/metabase/driver/mysql.clj
index a0538a0c4605aa2982d0c5b315fc7020606ca122..4a279c0b4292761259edb5c28bc1fb4af3fe4392 100644
--- a/src/metabase/driver/mysql.clj
+++ b/src/metabase/driver/mysql.clj
@@ -2,7 +2,7 @@
   (:require (clojure [set :as set]
                      [string :as s])
             [honeysql.core :as hsql]
-            [korma.db :as kdb]
+            [metabase.db.spec :as dbspec]
             [metabase.driver :as driver]
             [metabase.driver.generic-sql :as sql]
             [metabase.util :as u]
@@ -58,7 +58,7 @@
 (defn- connection-details->spec [details]
   (-> details
       (set/rename-keys {:dbname :db})
-      kdb/mysql
+      dbspec/mysql
       (update :subname #(str % connection-args-string (when-not (:ssl details)
                                                         "&useSSL=false"))))) ; newer versions of MySQL will complain if you don't explicitly disable SSL
 
diff --git a/src/metabase/driver/postgres.clj b/src/metabase/driver/postgres.clj
index bb03b648fcc5c72443d3f956ca788d4381cef5d6..fe56e61346dd8fdb6a9d3d1a2df672346bec95fd 100644
--- a/src/metabase/driver/postgres.clj
+++ b/src/metabase/driver/postgres.clj
@@ -5,7 +5,7 @@
                      [string :as s])
             [clojure.tools.logging :as log]
             [honeysql.core :as hsql]
-            [korma.db :as kdb]
+            [metabase.db.spec :as dbspec]
             [metabase.driver :as driver]
             [metabase.driver.generic-sql :as sql]
             [metabase.util :as u]
@@ -103,7 +103,7 @@
                ssl-params
                disable-ssl-params))
       (rename-keys {:dbname :db})
-      kdb/postgres))
+      dbspec/postgres))
 
 (defn- unix-timestamp->timestamp [expr seconds-or-milliseconds]
   (case seconds-or-milliseconds
diff --git a/src/metabase/driver/redshift.clj b/src/metabase/driver/redshift.clj
index a08b3e412ca0cb5b7132e50183a548c7efbd4f5b..50bad0c50561283582d4b8bd65246dee304258ab 100644
--- a/src/metabase/driver/redshift.clj
+++ b/src/metabase/driver/redshift.clj
@@ -2,16 +2,16 @@
   "Amazon Redshift Driver."
   (:require [clojure.java.jdbc :as jdbc]
             [honeysql.core :as hsql]
-            [korma.db :as kdb]
-            (metabase [config :as config]
-                      [driver :as driver])
+            [metabase.config :as config]
+            [metabase.db.spec :as dbspec]
+            [metabase.driver :as driver]
             (metabase.driver [generic-sql :as sql]
                              [postgres :as postgres])
             [metabase.util :as u]
             [metabase.util.honeysql-extensions :as hx]))
 
 (defn- connection-details->spec [details]
-  (kdb/postgres (merge details postgres/ssl-params))) ; always connect to redshift over SSL
+  (dbspec/postgres (merge details postgres/ssl-params))) ; always connect to redshift over SSL
 
 (defn- date-interval [unit amount]
   (hsql/call :+ :%getdate (hsql/raw (format "INTERVAL '%d %s'" (int amount) (name unit)))))
diff --git a/src/metabase/driver/sqlite.clj b/src/metabase/driver/sqlite.clj
index f7c5a893e8faf0da9bb016bf3bdd7d891428ed5f..0f080076bf79d81ac0248c72420494985e0d79b7 100644
--- a/src/metabase/driver/sqlite.clj
+++ b/src/metabase/driver/sqlite.clj
@@ -2,8 +2,8 @@
   (:require [clojure.set :as set]
             (honeysql [core :as hsql]
                       [format :as hformat])
-            [korma.db :as kdb]
             [metabase.config :as config]
+            [metabase.db.spec :as dbspec]
             [metabase.driver :as driver]
             [metabase.driver.generic-sql :as sql]
             [metabase.util :as u]
@@ -143,7 +143,7 @@
   (merge (sql/ISQLDriverDefaultsMixin)
          {:active-tables             sql/post-filtered-active-tables
           :column->base-type         (sql/pattern-based-column->base-type pattern->type)
-          :connection-details->spec  (u/drop-first-arg kdb/sqlite3)
+          :connection-details->spec  (u/drop-first-arg dbspec/sqlite3)
           :current-datetime-fn       (constantly (hsql/raw "datetime('now')"))
           :date                      (u/drop-first-arg date)
           :prepare-value             (u/drop-first-arg prepare-value)
diff --git a/src/metabase/models/interface.clj b/src/metabase/models/interface.clj
index d040b04e42506bb3c2f322421138b6965665cb61..79d611560cfd8fe0bdf02cf0a0b2b810678e0b6c 100644
--- a/src/metabase/models/interface.clj
+++ b/src/metabase/models/interface.clj
@@ -295,7 +295,7 @@
                         :tag      (symbol (str (namespace-munge *ns*) \. instance))
                         :arglists ''([] [id] [& kvs])
                         :doc      (or docstr
-                                      (format "Korma entity for '%s' table; instance of %s." (name table-name) instance)))
+                                      (format "Entity for '%s' table; instance of %s." (name table-name) instance)))
          (-> (k/create-entity ~(name entity))
              (k/table ~table-name)
              (assoc ::entity true)
diff --git a/test/metabase/sync_database_test.clj b/test/metabase/sync_database_test.clj
index 8fb3f002026d02aa5d072698ec582ce124e8fbc2..4ab6a16ce4a09b257addd4acb6be85ac5d5ad7a9 100644
--- a/test/metabase/sync_database_test.clj
+++ b/test/metabase/sync_database_test.clj
@@ -54,11 +54,8 @@
 
 (driver/register-driver! :sync-test (SyncTestDriver.))
 
-(def ^:private users-table       (delay (Table, :name "USERS")))
-(def ^:private venues-table      (delay (Table (id :venues))))
-(def ^:private korma-users-table (delay (korma-entity @users-table)))
-(def ^:private users-name-field  (delay (Field (id :users :name))))
 
+(def ^:private venues-table (delay (Table (id :venues))))
 
 (defn- table-details [table]
   (into {} (-> (dissoc table :db :pk_field :field_values)
diff --git a/test/metabase/test/data/generic_sql.clj b/test/metabase/test/data/generic_sql.clj
index e9bec764bb30f7b5921582ff9887fec14001cb56..1e666c20bb40289e0eb31b7e6a668451a97995e7 100644
--- a/test/metabase/test/data/generic_sql.clj
+++ b/test/metabase/test/data/generic_sql.clj
@@ -52,7 +52,7 @@
 
   ;; Other optional methods
   (korma-entity [this, ^DatabaseDefinition dbdef, ^TableDefinition tabledef]
-    "*Optional* Return a korma-entity for TABLEDEF.")
+    "*Optional* Return an entity for TABLEDEF.")
 
   (prepare-identifier [this, ^String identifier]
     "*OPTIONAL*. Prepare an identifier, such as a Table or Field name, when it is used in a SQL query.
@@ -172,7 +172,7 @@
 ;;  Oracle doesn't understand the normal syntax for inserting multiple rows at a time so we'll insert them one-at-a-time instead)
 
 (defn load-data-get-rows
-  "Get a sequence of row maps for use in a korma `insert` when loading table data."
+  "Get a sequence of row maps for use in a `insert!` when loading table data."
   [driver dbdef tabledef]
   (let [fields-for-insert (mapv (comp keyword :field-name)
                                 (:field-definitions tabledef))]