# Databases and OCaml

**URL:** <https://discuss.ocaml.org/t/databases-and-ocaml/913>\
**Category:** Learning\
**Tags:** databases, faq\
**Created:** [October 3, 2017, 2:21pm UTC](https://discuss.ocaml.org/t/databases-and-ocaml/913 "2017-10-03T14:21:09Z")\
**Posts on this page:** 17\
**Page:** 1

<div class="post-metadata">

**Author:** ![bobbypriambodo](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/bobbypriambodo/32/179_2.png) [@bobbypriambodo](https://discuss.ocaml.org/u/bobbypriambodo)\
**Post date:** [October 3, 2017, 2:21pm UTC](https://discuss.ocaml.org/t/databases-and-ocaml/913/1 "2017-10-03T14:21:09Z")

</div>

I’ve been hovering around for the past few weeks looking for an adequate database binding library for use with OCaml. So far the most supported ones seems to be [PGOCaml](https://github.com/darioteixeira/pgocaml), [postgresql-ocaml](https://github.com/mmottl/postgresql-ocaml), and [ocaml-mysql](http://ygrek.org.ua/p/ocaml-mysql/). The latter two are bindings for the respective C APIs (libpq and libmysqlclient), which seems to be too low-level (and blocking)… and PGOCaml, while widely suggested, uses the deprecated camlp4 which doesn’t seem to play well with jbuilder (it could be done I think, just some extra work is involved).

This came as a bit of a shock since I thought interacting with databases is quite a common task in any programming language.

Is there an inherent problem with modelling database interactions with OCaml that makes it hard to build a proper abstractions around it? Are there simply very few OCaml devs dealing with databases? Or are the solutions above deemed adequate enough to fulfill the use-cases?

Also, if you are writing (or have written) OCaml programs that uses databases in some way, what lib do you use and why?

---

<div class="post-metadata">

**Author:** ![zozozo](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/zozozo/32/59_2.png) [@zozozo](https://discuss.ocaml.org/u/zozozo)\
**Post date:** [October 3, 2017, 3:06pm UTC](https://discuss.ocaml.org/t/databases-and-ocaml/913/2 "2017-10-03T15:06:46Z")

</div>

I use [sqlexpr](https://github.com/mfp/ocaml-sqlexpr), as it gives a nice ppx extension for typed requests, as well as support for using it with lwt.

EDIT: Note that sqlexpr is a wrapper around [ocaml-sqlite](https://github.com/mmottl/sqlite3-ocaml)

---

<div class="post-metadata">

**Author:** ![gersonmoraes](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/gersonmoraes/32/485_2.png) [@gersonmoraes](https://discuss.ocaml.org/u/gersonmoraes)\
**Post date:** [October 3, 2017, 4:41pm UTC](https://discuss.ocaml.org/t/databases-and-ocaml/913/3 "2017-10-03T16:41:35Z")

</div>

For low-level there’s also [ocaml-mariadb](https://github.com/andrenth/ocaml-mariadb) _(based on libmariadbclient-dev)_, which provides access to both traditional MySQL blocking api and the nonblocking api introduced in MariaDB.

There’s also the [Sequoia](https://github.com/andrenth/sequoia) project (of the same author) that is a _high level type-safe query builder_. It imposes some limitations on your project and in the type of queries you can do, but it’s a good example of the type of abstractions that can be made on top of OCaml type system.

---

<div class="post-metadata">

**Author:** ![hcarty](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/hcarty/32/1824_2.png) [@hcarty](https://discuss.ocaml.org/u/hcarty)\
**Post date:** [October 4, 2017, 3:00am UTC](https://discuss.ocaml.org/t/databases-and-ocaml/913/4 "2017-10-04T03:00:20Z")

</div>

ocaml-mysql and many other bindings to C libraries can be used concurrently with other OCaml code by using native threads. I do this in Lwt-based applications quite often.

[Lwt\_preemptive](https://ocsigen.org/lwt/dev/api/Lwt_preemptive) provides a nice interface for mixing native threads with Lwt promises.

---

<div class="post-metadata">

**Author:** ![didier-wenzek](https://avatars.discourse-cdn.com/v4/letter/d/9de0a6/32.png) [@didier-wenzek](https://discuss.ocaml.org/u/didier-wenzek)\
**Post date:** [October 4, 2017, 8:01am UTC](https://discuss.ocaml.org/t/databases-and-ocaml/913/5 "2017-10-04T08:01:52Z")

</div>

This is a bit off topic.

Having a quick glance over the sequoia API, I was intrigued by the way type information is vehicle along the query under construction. An acknowledgment at the end of the [README](https://github.com/andrenth/sequoia#acknowledgements) unveils [the mechanisms](https://sympa.inria.fr/sympa/arc/caml-list/2016-09/msg00111.html).

This is really bright, and I promised myself to take a few hours to play with the two solutions proposed in this thread!

---

<div class="post-metadata">

**Author:** ![bobbypriambodo](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/bobbypriambodo/32/179_2.png) [@bobbypriambodo](https://discuss.ocaml.org/u/bobbypriambodo)\
**Post date:** [October 4, 2017, 9:57am UTC](https://discuss.ocaml.org/t/databases-and-ocaml/913/6 "2017-10-04T09:57:07Z")

</div>

> [@zozozo](#):
>
> I use sqlexpr

Too bad sqlexpr only supports sqlite currently, would be great to have it support other DBs too.

> [@gersonmoraes](#):
>
> There’s also the Sequoia project

Sequoia’s API looks wonderful! Reminds me of Elixir’s Ecto library. Will definitely check it out.

> [@hcarty](#):
>
> ocaml-mysql and many other bindings to C libraries can be used concurrently with other OCaml code by using native threads. I do this in Lwt-based applications quite often.

Yes I’ve played around with Lwt\_preemptive although haven’t got anything running with postgresql-ocaml. Will keep trying and perhaps publish it if I managed to generalize it as a Lwt-wrapped postgresql-ocaml. I’m still not sure what the tradeoffs for using Lwt\_preemptive are though.

Really appreciate the replies! If you have more please keep 'em coming 🙂

---

<div class="post-metadata">

**Author:** ![BrendanLong](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/brendanlong/32/522_2.png) [@BrendanLong](https://discuss.ocaml.org/u/BrendanLong)\
**Post date:** [October 6, 2017, 9:58pm UTC](https://discuss.ocaml.org/t/databases-and-ocaml/913/7 "2017-10-06T21:58:53Z")

</div>

[Arena](https://www.arena.io/) is working on an OCaml-native PostgreSQL library (a fork of PGOcaml). I’m trying to nail down the interface so we can open it up without having a lot of interface churn.

In my opinion, writing a database library in OCaml is pretty nice. I suspect the lack of them is mainly because there’s just not that many people using OCaml at all. While it’s annoying that the core developers haven’t “blessed” an async implementation, it’s cool that we can use functors to write a database client that works for both Lwt and Async.

---

<div class="post-metadata">

**Author:** ![bobbypriambodo](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/bobbypriambodo/32/179_2.png) [@bobbypriambodo](https://discuss.ocaml.org/u/bobbypriambodo)\
**Post date:** [October 8, 2017, 3:36am UTC](https://discuss.ocaml.org/t/databases-and-ocaml/913/8 "2017-10-08T03:36:29Z")

</div>

> [@BrendanLong](#):
>
> Arena is working on an OCaml-native PostgreSQL library (a fork of PGOcaml).

Ooh I’m looking forward to this 🙂

> [@BrendanLong](#):
>
> it’s cool that we can use functors to write a database client that works for both Lwt and Async.

Yeah functors are definitely interesting. I’m also trying to wrap postgresql-ocaml with a friendlier API, specifically Lwt/Async-friendly. Still in early stages, though.

---

<div class="post-metadata">

**Author:** ![ghuysmans](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/ghuysmans/32/595_2.png) [@ghuysmans](https://discuss.ocaml.org/u/ghuysmans)\
**Post date:** [October 13, 2017, 8:24am UTC](https://discuss.ocaml.org/t/databases-and-ocaml/913/9 "2017-10-13T08:24:37Z")

</div>

There are two PPX for PGOCaml… If I remember well, they are referenced there: [https://github.com/darioteixeira/pgocaml/issues/9](https://github.com/darioteixeira/pgocaml/issues/9).

---

<div class="post-metadata">

**Author:** ![bobbypriambodo](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/bobbypriambodo/32/179_2.png) [@bobbypriambodo](https://discuss.ocaml.org/u/bobbypriambodo)\
**Post date:** [October 15, 2017, 10:05am UTC](https://discuss.ocaml.org/t/databases-and-ocaml/913/10 "2017-10-15T10:05:37Z")

</div>

> [@bobbypriambodo](#):
>
> I’m also trying to wrap postgresql-ocaml with a friendlier API, specifically Lwt/Async-friendly. Still in early stages, though.

So I managed to build something that I’m quite satisfied of (although still much room for improvement), Ezpostgresql (name shamelessly inspired by Ezjsonm, as I am bad at giving names):

> **[GitHub - bobbypriambodo/ezpostgresql: Lwt-friendly wrapper for...](https://github.com/bobbypriambodo/ezpostgresql)**
>
> Lwt-friendly wrapper for postgresql-ocaml which supports connection pooling. - GitHub - bobbypriambodo/ezpostgresql: Lwt-friendly wrapper for postgresql-ocaml which supports connection pooling.

At this point it’s only compatible with Lwt since I’m not sure how to make one that can work with both Async and Lwt. You can see the examples on the README for more info. And yes, it also supports connection pooling out of the box via Lwt\_pool. Do note it’s still WIP and by no means stable yet!

Feedbacks are welcome 🙂

---

<div class="post-metadata">

**Author:** ![paurkedal](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/paurkedal/32/586_2.png) [@paurkedal](https://discuss.ocaml.org/u/paurkedal)\
**Post date:** [October 15, 2017, 11:10am UTC](https://discuss.ocaml.org/t/databases-and-ocaml/913/11 "2017-10-15T11:10:37Z")

</div>

`postgresql-ocaml` also has async bindings which can be used to implement concurrent interfaces without preemptive threading. This takes a bit more work, of course, so it may be a second iteration. I’m using it for the PostgrSQL driver of [Caqti](https://github.com/paurkedal/ocaml-caqti). On the other hand I had to resort to preemptive threading for the SQLite3 driver.

---

<div class="post-metadata">

**Author:** ![bobbypriambodo](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/bobbypriambodo/32/179_2.png) [@bobbypriambodo](https://discuss.ocaml.org/u/bobbypriambodo)\
**Post date:** [October 15, 2017, 11:31am UTC](https://discuss.ocaml.org/t/databases-and-ocaml/913/12 "2017-10-15T11:31:09Z")

</div>

Good point, yeah I’d like to explore that too, but that means reading more C docs 😅 I aimed to flesh out the API first and see if I can get it usable.

Caqti looks really cool! I missed it on my first search. Will take a look and see if I can steal some ideas (with proper credits of course!).

---

<div class="post-metadata">

**Author:** ![paurkedal](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/paurkedal/32/586_2.png) [@paurkedal](https://discuss.ocaml.org/u/paurkedal)\
**Post date:** [October 15, 2017, 11:55am UTC](https://discuss.ocaml.org/t/databases-and-ocaml/913/13 "2017-10-15T11:55:28Z")

</div>

I should have mentioned Caqti myself when I saw this thread, though haven’t tried to promote it, since I consider making intrusive changes to the API. In case anyone want’s to contribute their opinion, we could discuss the gory details under the [Stabilize the API](https://github.com/paurkedal/ocaml-caqti/issues/4) issue.

---

<div class="post-metadata">

**Author:** ![BrendanLong](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/brendanlong/32/522_2.png) [@BrendanLong](https://discuss.ocaml.org/u/BrendanLong)\
**Post date:** [December 21, 2017, 2:34pm UTC](https://discuss.ocaml.org/t/databases-and-ocaml/913/14 "2017-12-21T14:34:06Z")

</div>

If anyone is interested, I put Arena’s new Postgres library (PGX) [on GitHub](https://github.com/arenadotio/pgx). There’s still a lot of work to do before I make a bigger announcement, but if you want something similar to PG’OCaml with a higher-level interface and more tests it might be for you.

At this point we’re definitely planning to change the interface in non-backwards-compatible ways, and we’re also looking for feedback on the interface. Our goals (in order of priority) are:

- Safety – the library should prevent you from doing things wrong whenever possible
- Ease of use – Try to reduce boilerplate as much as possible and make it obvious how to do things right
- Speed – If we can get it without hurting the other two

---

<div class="post-metadata">

**Author:** ![UnixJunkie](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/unixjunkie/32/638_2.png) [@UnixJunkie](https://discuss.ocaml.org/u/UnixJunkie)\
**Post date:** [December 22, 2017, 2:11am UTC](https://discuss.ocaml.org/t/databases-and-ocaml/913/15 "2017-12-22T02:11:58Z")

</div>

On the minimalist side of things, there is a dbm package in opam.  
“Binding to the NDBM/GDBM Unix databases”

---

<div class="post-metadata">

**Author:** ![c-cube](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/c-cube/32/1727_2.png) [@c-cube](https://discuss.ocaml.org/u/c-cube)\
**Post date:** [February 1, 2018, 4:58pm UTC](https://discuss.ocaml.org/t/databases-and-ocaml/913/16 "2018-02-01T16:58:22Z")

</div>

[https://github.com/paurkedal/ocaml-caqti](https://github.com/paurkedal/ocaml-caqti) is now on opam, btw. kudos to @paurkedal! Hopefully the community will rally around it as a common interface to DBs, as in other languages.

---

<div class="post-metadata">

**Author:** ![ashish](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/ashish/32/34_2.png) [@ashish](https://discuss.ocaml.org/u/ashish)\
**Post date:** [February 2, 2018, 3:55pm UTC](https://discuss.ocaml.org/t/databases-and-ocaml/913/17 "2018-02-02T15:55:20Z")

</div>

> [@bobbypriambodo](#):
>
> PGOCaml, while widely suggested, uses the deprecated camlp4

The PG’OCaml package requires campl4 to be installed. This is an annoyance, but to be clear, you don’t have to use the camlp4 aspects of the library for it to be useful. You can simply call its pure ocaml functions.
