Database ORM - Haskell

Welcome to the Functional Programming Zulip Chat Archive. You can join the chat here.

Sridhar Ratnakumar

Which database ORM would you all choose if you were to pick one for a new Haskell project?

Sridhar Ratnakumar

I'm familiar with Beam, but I am curious about others' views.

Torsten Schmits

is ORM really an applicable term in haskell? I only associate it with object adapters that execute queries on OO method access, like users.getPosts(5)

Torsten Schmits

anyway, I've only used Hasql, and I'm quite satisfied. all the others didn't really look pleasant, too intrusive

Sridhar Ratnakumar

s/ORM/type-safe SQL mapper/?

Sridhar Ratnakumar

(stolen straight from the beam library synopsis)

Sridhar Ratnakumar

Is persistent ... still relevant? Seems to be from the yesod days (a library that no one uses today?)

Joel McCracken

plenty of people still use yesod and persistent

Joel McCracken

esqueleto has had a flurry of work recently

Sridhar Ratnakumar

It looks like beam doesn't use that, and has its own backend, eg: http://hackage.haskell.org/package/beam-sqlite

Torsten Schmits

so with Hasql you create two values for codec, then combine them with some sql that you can write as a string or with TH or as a data type value, into a Statement value.
then you do something like runSession connection statement and that's it, all the resource acquisition can be done any way you please, which I find very helpful for writing flexible code with it.

Bolt

I had a go at Beam and it was quite nice

Bolt

data-basic also looks cool!

Georgi Lyubenov // googleson78

Sridhar Ratnakumar said:

How up to date is this blog post? https://williamyaoh.com/posts/2019-12-14-typesafe-db-libraries.html

I can for certain say that it's not up-to-date with esqueleto (when using the newer stuff) re these things:

  • you cannot forget ons
  • you can do joins on subqueries (and unions, intersects, etc)

for me it's way easier than writing raw sql, but maybe it's because of my lack of experience with sql

Vladimir Ciobanu

I am fairly certain that persistent + esqueletto is the default the vast majority of haskell projects go for. It's by far the most popular, AFAIK. On hackage, for example, it has an order of magnitude more downloads than beam.

Not to say it's that much better, it may even not be, but it is definitely still the king in this space.

Mats Rauhala

Also note that the beam guys don't really seem to do any hackage (nor stackage) releases, you are expected to use the tip of master. TBH beam is one of those libraries I want to like, but I can't with good conscience recommend it for production stuff

Vladimir Ciobanu

Is there even such a thing as a stackage release? I always thought stackage has lts/nightly versions which can only pin hackage versions. Can you also point to stuff on github directly, within an lts?

Mats Rauhala

IIUC one still needs to request their package to be taken to stackage. But it will eventually drop out of there if it's no longer buildable with the given stackage snapshot. And since there has been no beam releases in 1½ years, it's pretty much unbuildable with the modern stackage package sets

James Sully

@Sridhar Ratnakumar do people really not use Yesod? What makes you say that? What do they use instead? Servant, scotty?

Torsten Schmits

I use servant and obelisk

Mats Rauhala

I use servant approximately 99% of the time. But yesod is still a valid option, more so if you're not doing APIs but websites.

Even then, yesod and persistent aren't in any way married together, any more than yesod & conduit is. They just happen to be from the same prolific author (Snoyman)

Georgi Lyubenov // googleson78

for a rails-like experience I think yesod is fine (meaning very "just works" out of the box and there is a well-documented "kings road" on how to do things, I haven't actually used rails :D :D)

Vladimir Ciobanu

Yeah, my go-to is actually servant + persistent/esqueletto, but I'm interested in trying out other options like beam or opaleye.

Mats Rauhala

I usually prefer sqlite-simple / postgresql-simple. SQL is a powerful language, I feel like hiding it behind an ORM / whatever is more of a disservice.

Want type safety? Write type safe functions :shrug:

getPerson :: (MonadReader r m, HasDB r, MonadIO m) => SocialSecNumber -> m (Maybe Person)
getPerson = ...

It doesn't really matter, what the implementation of that function is. Write a test for it (you write tests for you queries, right?) and now you have a type safe interface for it.

Georgi Lyubenov // googleson78

I don't understand the logic behind this sentiment
what's the difference between making this claim for sql, and for any other untyped language?

Georgi Lyubenov // googleson78

surely there is some type system (possibly dependent) that fits with sql's terms (or at least most of the "well-formed" terms) - I don't see why you wouldn't want to use it (especially when you're also provided with an escape hatch when the type system is too weak for your query to be written in it)

Mats Rauhala

Does there have to be a difference? It's the same as using C FFI, right? You provide your type safe interface for it

Georgi Lyubenov // googleson78

but when I'm writing a type-safe interface for C FFI I'm usually trying to write a library to wrap the C FFI, and then use it from my app

Mats Rauhala

Yes, but for example in beams case, it's providing you with a DSL over the SQL so that you can write your type safe interfaces using the DSL. This is akin to someone writing a DSL for writing a C shim so that you can do FFI over the DSL instead of interfacing with c using c.

James King

Depends. I don't pick an "ORM" by default -- relational SQL is a very rich language and you can only exploit the best features and best performance of your database by writing SQL.

James King

If it's a service I am hosting and running I'm not concerned about the need to be able to "swap out" databases.

James King

However if it's an application I may need to run on a variety of different configurations... different databases, etc, I'll reach for a higher level library, possibly even an ORM.

James King

And in Haskell that'd be Persistent probably.

Joel McCracken

I used to like SQL until I learned FP, relational algebra, and prolog. now SQL just feels arbitrary, ad-hoc, frustrating, inconsistent. Like, so many things that are entire language features should just be functions in a standard library. Like recursive queries, or window functions

Joel McCracken

(this really isn't me adding much to the conversation but I always kinda find it confusing when experienced FP people say they really like SQL; what am I missing? I really wish prolog/datalog had become the standard)

Mats Rauhala

I'm not saying I like SQL. I like relational algebra, but I feel the real world SQL (postgresql, mysql, sqlite, sqlserver etc) is so far removed relational algebra that you'll always end up having bad time shoehorning relational algebra to them. There's always an abstraction, a command, something, that the library is missing.

Sridhar Ratnakumar

I have never seen Yesod used in any open source projects. It seems as popular as Obelisk.

James King

To be fair I don't think there are many open source applications written in Haskell to serve as examples. I could be wrong but I don't think there are enough to have any kind of comparison, shootout, or benchmark.

Joel McCracken

https://github.com/lorepub/moot/ is the only one I know of :shrug:

Moot is a CFP and event management system! Contribute to lorepub/moot development by creating an account on GitHub.
codygman

At work we use persistent and esqueleto, but I might prefer beam or Opaleye... Not sure. Beam at least requires more type level knowledge and I found myself wanting to pepper in lots of TypeApplications to understand things.

There was another... Selda.. which seemed nice but I moved past it for some reason.

codygman

Summary: persistent+esqueleto is pretty simple and type safe, beam or Opaleye get you more type safety at the cost of usage complexity which I suspect would fade into the background after a few weeks of use