Skip to content


Subversion checkout URL

You can clone with
Download ZIP
A library to create and manipulate SQL database schemas with migrations support.
Clojure Shell
tag: 0.6.0

Fetching latest commit…

Cannot retrieve the latest commit at this time

Failed to load latest commit information.


Lobos is a library to create and manipulate abstract SQL database schemas and applying them to any supported RDBMS. It is based on the original ClojureQL but exclude the query language part which is better handled by the new ClojureQL project. It aims to add higher-level features like declarative schema manipulation and built-in migration support.

This is currently an early release, use at your own risk. You can have a look at the roadmap for more information about future releases and consult the history to see what have been done.

Lobos supports H2, MySQL, PostgreSQL, SQLite and SQL Server. You'll need to add the relevant JDBC driver manually.


Here's a quick overview of how it works in its current state.


First you'll need to use at least the following namespaces:

(use 'lobos.connectivity

You'll also need to include the namespace corresponding to the database you want to communicate with:

(use 'lobos.backends.postgresql)

Then you'll need a connection. The following example define a test connection and makes it the default global connection:

(def db
     {:classname "org.postgresql.Driver"
      :subprotocol "postgresql"
      :user "test"
      :password "test123"
      :subname "//localhost:5432/test"})

(open-global db)

You can send DDL statements (called actions) directly to a connected database like this:

user> (create db (table :users (integer :id :unique)))

You can omit the connection altogether and the actions will use the default one.

user> (drop (table :users (integer :id :unique)))


You can use a schema which you'll first need to define:

(defschema sample-schema :public)

Then you can make that schema the default one:

(set-default-schema sample-schema)

Now you can call actions on the database to which the schema is attached and the actions will return the schema definition instead of nil:

user> (create (table :users (integer :id :unique)))
user> (drop (table :users))

More Complex Examples

Lobos now supports a quite comprehensive set of features for creating tables, here's a more complex example defining a complete schema:

(ns lobos.test.sample-schema
  (:refer-clojure :exclude [alter compile drop
                            bigint boolean char double float time])
  (:use (lobos core schema)))

(defn surrogate-key [table]
  (integer table :id :auto-inc :primary-key))

(defn datetime-tracked [table]
  (-> table
      (timestamp :updated_on)
      (timestamp :created_on [:default :now])))

(defn refer-to [table ptable]
  (let [cname (-> (->> ptable name butlast (apply str))
                  (str "_id")
    (integer table cname [:refer ptable :id :on-delete :set-null])))

(defmacro tabl [name & elements]
  `(-> (table ~name

(defschema sample-schema :lobos

  (tabl :users
    (varchar :name 100 :unique)
    (check :name (> :length/name 1)))

  (tabl :posts
    (varchar :title 200 :unique)
    (text :content)
    (refer-to :users))

  (tabl :comments
    (text :content)
    (refer-to :users)
    (refer-to :posts)))

To create that schema, use the create-schema action:

user> (use 'lobos.test.sample-schema)
user> (create-schema sample-schema)

There also the alter action that let you manipulate tables:

user> (alter :add (table :users (text :about-me)))
user> (alter :add (table :users
                    (text :location)
                    (text :occupation)))
user> (alter :add (table :comments (check :comment-limit (< :length/content 144))))
user> (alter :modify (table :users (column :location [:default "Somewhere"])))
user> (alter :drop (table :users (column :occupation)))
user> (alter :rename (table :users (column :location :to :origin)))

The drop action has the optional behavior parameter that works even on database without built-in support for it:

user> (drop sqlserver-spec (table :users) :cascade)


You can always set the debug level to see the compiled statement:

user> (set-debug-level :sql)
user> (create (table :users (integer :id :unique)))
CREATE TABLE "lobos"."users" ("id" INTEGER, CONSTRAINT "unique_id" UNIQUE ("id"))

As you can see Lobos use delimited identifiers by default and schema qualified identifiers when an action use a schema.


Lobos includes a database analyzer which use the database meta-data to construct an abstract schema definition from an actual database schema. This feature is only experimental for the moment and is used internally to update the global schema map and for integration testing. You can try it out like that:

user> (use 'lobos.analyzer)
user> (analyze-schema :test)
user> (-> :test analyze-schema :elements :users :columns :name)
user> (-> :test analyze-schema :elements :posts :constraints :posts_fkey_user_id)

This feature may eventually be split into its own project and is quite limited in its current form. Currently it doesn't support check constraints and need a custom JDBC driver for SQLite.


Lobos is available through Clojars.

For the latest release, in Cake/Leiningen:

[lobos "0.6.0"]

in Maven:



Copyright (C) 2010 Nicolas Buduroi. All rights reserved

Distributed under the Eclipse Public License, the same as Clojure. See the file epl-v10.html in the project root directory.

Something went wrong with that request. Please try again.