Skip to content
This repository

Relational persistence for Clojure

branch: master

Fetching latest commit…


Cannot retrieve the latest commit at this time

Octocat-spinner-32 script
Octocat-spinner-32 src
Octocat-spinner-32 test
Octocat-spinner-32 .cljrc.clj
Octocat-spinner-32 .gitignore
Octocat-spinner-32 COPYING
Octocat-spinner-32 README.textile
Octocat-spinner-32 project.clj


Carte is a relational mapping library for Clojure which maps nested immutable data structures to an underlying relational database management system. Carte is alpha software and will not be stable until it reaches version 1.0. If you plan to use it in a real project, be ready to contribute and fix the problems that you will find.

Carte is meant to be used in a bottom-up style, where you define how to work with data at a low level and then use this mechanism in the higher levels of you application.

The project is currently being developed against MySQL but will someday be database independent.

An Example

The following simulated REPL session shows some of the features of Carte.

Suppose we have a database with the schema shown below.

Sample Schema

We need to connect to it…

user> (def conn {:connection {:classname "com.mysql.jdbc.Driver"
                              :subprotocol "mysql"
                              :subname "//localhost/carte_test_db"
                              :user "carte_db_user"
                              :password "123456789"}})

…and define the model…

user> (def data-model
          (track (belongs-to :album))
          (album (many-to-many :artist)
                 (many-to-one :genre)
                 (many-to-one lead_vocals :artist :lead_vocals_id))))

…and package this up into the handle that we can use.

user> (def db (merge-with-attrs conn data-model))

We may now grab a bunch of data,…

user> (def all-artists (fetch db :artist :with [:albums :with :tracks :genre]))
user> all-artists
[{:id 64,
  :name "Jack White",
  [{:release_date #<DateTime 2003-04-01T00:00:00.000-08:00>,
    :title "Elephant",
    :id 50,
    :genre_id 19,
    :lead_vocals_id 64,
    [{:album_id 50, :name "Seven Nation Army", :id 114}
     {:album_id 50, :name "Black Math", :id 115}
     {:album_id 50,
      :name "Girl, You Have No Faith In Medicine",
      :id 116}],
    :genre {:id 19, :name "Rock"}}
   {:release_date #<DateTime 2006-05-16T00:00:00.000-07:00>,
    :title "Broken Boy Soldiers",
    :id 49,
    :genre_id 19,
    :lead_vocals_id nil,
    [{:album_id 49, :name "Hands", :id 117}
     {:album_id 49, :name "Level", :id 118}
     {:album_id 49, :name "Steady As She Goes", :id 119}
     {:album_id 49, :name "Call It a Day", :id 120}
     {:album_id 49, :name "Together", :id 121}],
    :genre {:id 19, :name "Rock"}}]}

…query it,…

user> (find-in [:albums {:title "Elephant"} :tracks :name] all-artists)
["Seven Nation Army" 
 "Black Math" 
 "Girl, You Have No Faith In Medicine" 
 "Seven Nation Army"

…change it,…

user> (def changed-artists (vary-in all-artists :artist {:name "Jack White"} {:name "Jack Daniels"}))
user> changed-artists
  [{:genre {:name "Rock", :id 19},
    [{:id 114, :name "Seven Nation Army", :album_id 50}
     {:id 115, :name "Black Math", :album_id 50}
     {:id 116,
      :name "Girl, You Have No Faith In Medicine",
      :album_id 50}],
    :lead_vocals_id 64,
    :genre_id 19,
    :id 50,
    :title "Elephant",
    :release_date #<DateTime 2003-04-01T00:00:00.000-08:00>}
   {:genre {:name "Rock", :id 19},
    [{:id 117, :name "Hands", :album_id 49}
     {:id 118, :name "Level", :album_id 49}
     {:id 119, :name "Steady As She Goes", :album_id 49}
     {:id 120, :name "Call It a Day", :album_id 49}
     {:id 121, :name "Together", :album_id 49}],
    :lead_vocals_id nil,
    :genre_id 19,
    :id 49,
    :title "Broken Boy Soldiers",
    :release_date #<DateTime 2006-05-16T00:00:00.000-07:00>}],
  :name "Jack Daniels",
  :id 64}

…and save our changes.

user> (save-or-update db changed-artists)
user> (fetch-one db :album [:title] {:title "Elephant"} :with :lead_vocals)
{:title "Elephant",
 :id 50,
 :lead_vocals {:id 64, :name "Jack Daniels"}}

For more details, please see the documentation in the Carte Wiki.


You may use Carte in your Leiningen project by adding the following to your :dependencies

[carte/carte "0.2.0"]

To use Carte from a Maven project, add the following dependency:


…which comes from Clojars…



Copyright © 2010 Brenton Ashworth

Distributed under the Eclipse Public License, the same as Clojure uses. See the file COPYING.

Something went wrong with that request. Please try again.