(defdb prod (postgres {:db "korma"
                       :user "db"
                       :password "dbpass"}))

(defentity address)
(defentity user
  (has-one address))

(select user
  (with address)
  (fields :firstName :lastName :address.state)
  (where {:email "korma@sqlkorma.com"}))

Clojure is beautiful.

It can make SQL beautiful too.

Korma is a domain specific language for Clojure that takes the pain out of working with your favorite RDBMS. Built for speed and designed for flexibility, Korma provides a simple and intuitive interface to your data that won't leave a bad taste in your mouth.

A quick overview

  • Composable from the ground up.

    All the parts of a query in Korma can be composed at will. This allows you to construct queries over time and in virtually any way you can dream of.

    (def base (-> (select* "user")
                (fields :id :username)
                (where {:email [like "*@gmail.com"]})))
    
    (def ordered-and-active (-> base
                              (where {:active true})
                              (order :created)))
    
    (def constrained (-> ordered-and-active
                       (limit 20)))
    
    (select constrained)
    
  • Take the pain out of relations.

    Korma entities handles relationships for you. Just specify what kind of relationship it is and all the joining will be done for you.

    (defentity email)
    (defentity address)
    (defentity account)
    
    (defentity users
      (has-one email)
      (has-many address)
      (belongs-to account))
    
    (select users
      (fields :email.email :address.state :account.name)
      (with email)
      (with address)
      (with account))
    
  • Built for the real world.

    Real projects are never simple. As such, Korma was designed with flexibility in mind. Couple that with fast query generation and you have a library meant to play in the big leagues.

    (defentity address
      (table :__addresses :address))
    
    (defentity users
      (table :somecrazy_table_name :users)
      (pk :userID)
      (has-many address {:fk :userID}))
    
    (select users
      (with address)
      (where {:last_login [< a-week-ago]}))
    
    (select users
      (aggregate (count :*) :cnt)
      (where (or (> :visits 20)
                 (< :last_login a-year-ago))))