HN2new | past | comments | ask | show | jobs | submitlogin

I tried Clojure, but when i look for a good ORM, what i see is a paid library.


In Clojure ORMs aren't really that popular considering most Clojurists just use the built in datatypes (e.g. maps) to represent data. There are no classes as such (unless you use Java interop). If you need a query builder the honeysql library is really nice.


Lol yup ! "It's Maps All The Way Down"


> just use the built in datatypes (e.g. maps)

Well, then, MRM: Map-Relational-Mapper.


There's https://www.hugsql.org/ for example. It takes maps for inserts and updates, and returns maps for selects. Other database access libraries over the years have typically shared that characteristic.

If you want to convert between maps that map directly to tables and some other structure, manipulating maps in Clojure is easy.


Expanding on this a bit, Clojure, as a language, is fundamentally against the idea of ORMs in its design.

Objects / classes are not so much the problem, per se—it's specifically that ORMs fundamentally involve scattering uncoordinated mutable state throughout the application. A foundational thesis of Clojure is that mutation is a tremendous source of bugs, and should be avoided / thoughtfully limited.

Once you let the unmanaged mutation genie out of the bottle, it's almost impossible to put back in.

More concretely, I used to work extensively with Rails; I loved ActiveRecord (ORM) when I first started out—it makes basic things so easy.

Later I worked on a large Rails app supporting millions of users...we used ActiveRecord extensively, and had a very talented team. ActiveRecord worked fine most of the time, but I have bad memories of spending hours or even days tracking down user-reported bugs.

I'd try to figure out how to recreate the user's state locally, even cloning pieces of the production database to work with their exact DB data, but whatever state the program had gotten into was a large graph of (all!) mutable objects. How was that flag getting set? What code could have done it? When? And the answer is basically ANYTHING at ANY TIME that could possibly get a reference to the object. And web applications are far from the worst offenders in this space because the request / response cycle is (usually) fairly globally stateless.

Clojure is the exact opposite of that experience.

The state of a Clojure program will most likely comprised of data literals (think JSON data types, if you don't have experience with Clojure / Lisp data). Printable data literals. Connect to the errant server, serialize the state, read it from your machine, and you're there. It's coherent, stable, serializable, transmittable, simple.

Who can mutate your data? No one. You have an immutable reference (maybe others do too, but reading is a fundamentally safe operation). How does it change? Only along the explicit path of computations you're working through (it doesn't change, actually, you choose to hold onto a new reference to derived data when you want to).

Or, if you really need a mutable escape hatch (like, say, you're holding a handle to a database), every type of mutation in (core) Clojure has defined (and thoughtfully so) concurrency semantics. You won't see a bunch of notes in Clojure API docs that say things like "not thread safe" like you see in JavaDocs.

TLDR: Clojure will happily give you object-like read-only views into your database (like Datomic's `datomic.api/entity`), or help you write queries with a knowledge of your database schema, but most Clojure persistence solutions will explicitly coordinate mutation into a single 'site' because that's the only way maintain a coherent view of state-over-time. And that single-mutation-site story is the opposite of what ORMs (as commonly defined) do.


This deserves to be used as Clojure marketing material. It’s great.


Very kind of you to say. Thank you.


Underrated! (Thank you.)


Typical ORM's are a mismatch for Clojure. Two pretty good options to generate SQL are honeysql and hugsql. They both attack the problem from two different directions.


HugSQL is great if you like to deal with your SQL directly.


https://www.hugsql.org/ seems pretty nice. Not exactly an ORM, but probably does what you need.


I'd go further and say it's nothing like an ORM. It's just a library for passing values to an SQL query.


You don't want an Object Relational Mapping library in a language that discourages object orientation.


If you really want to melt your brain (in a GOOD way) look at XTDB it's a datalog-query-based DB. Like dataomic but free.


If your'e using PostgreSQL, checkout https://github.com/retro/penkala . It provides most of the things you would expect when dealing with the database without it being an ORM. IF you're interested in how the API looks checkout https://github.com/retro/penkala/blob/master/test/com/verybi... which implements most of the queries that can be found on https://www.postgresqltutorial.com

note: I'm the author of Penkala


Rich Hickey said it best:

"ORM's provide 'OH MY GOD' complexity"

(from his "Simple Made Easy" talk - I might have the quote only 90% correct, but it's pretty darn close to that).


There's this:

https://github.com/metabase/toucan

But beware what you do with it. Avoid DB side effects from business logic.


Hi, Toucan library author here.

+1 on avoiding side effects from business logic. This applies not just to Toucan, but to database code in general. Toucan is there to give you a way to define behaviors when interacting with your application database, for example transforming certain columns when you fetch rows from a certain table from the database. It's that plus utility functions for interacting with your database. Not really an ORM.

Either way, Toucan 2 is out now: https://github.com/camsaul/toucan2 I'm still working on fully documenting it but it's already being used in the wild and Toucan 1 will probably be archived soon


Since the "O" in "ORM" stands for "Object" why are you surprised that a functional language like Clojure doesn't provide an ORM?


HoneySQL allows you to write SQL via data structures so you can compose that. Gives you a lot of power.


Clojurists objectively dislike ORMS. Too much magic.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: