Welcome! Please see the About page for a little more info on how this works.

+4 votes
in Libs by

I'm looking for some comparison between Ragtime and Migratus. Love to hear from anyone having experience with both, or either; even pros and cons sort would do.

Thanks.

2 Answers

0 votes
by

TBH, I never used the second one, only came across a few issues on Ragtime's GH that request or compare some of their features.

From what I know (and also just learned about Migratus from its README):

  • Both are battle-tested by many
  • Both use raw SQL for "up"s and "downs":
  • Ragtime — in a single EDN file, but also supports :
    {:up ["CREATE TABLE IF NOT EXISTS foo (id bigint NOT NULL PRIMARY KEY);"] :down ["DROP TABLE IF EXISTS foo;"]}
  • Migratus — the same, but in two separate SQL files:
    CREATE TABLE IF NOT EXISTS foo(id BIGINT);
    and
    DROP TABLE IF EXISTS foo;
  • Both support multi-statements with --;; (because of a shared JDBC constraint)
  • Both support next.jdbc
  • Both can run "up"s/"down"s for individual migrations by ID
  • Ragtime recently implemented transactional DB initialization, after a user's request (Migratus's default behavior; :init-in-transaction? true)
  • Both can be used can be used programmatically
  • In Migratus, there are concepts of a :migration-dir "migrations/" and :init-script "init.sql" (from my experience, unavoidable with Ragtime as well and quite easy to have)
  • Migratus's rollback options are "just one (latest)" and "until ID", while Ragtime is more flexible here (having an index at hand, you can do whatever you want with it programmatically; for instance, I've implemented rollbacks such that they will rollback all migrations that were not already applied upon the app process start-up)
  • Ragtime implements conflict resolution strategies, catering e.g. for blue/green DB deployments (this is the ignore-future strategy that I employ in my projects)
  • Migratus supports templating/placeholders substitution (never used or needed this though, YMMV)
  • Migratus supports code-based migrations (if templating/placeholders substitution is not enough for some reason; again, never used or needed this though, YMMV)
  • Migratus supports generating migration files for you (never felt such a need on a greenfield project, but may be crucial for large existing ones)
  • Migratus just recently added support for squashing migrations (but I can hardly imagine how many migrations you need to have in your app in order to require this feature)
  • Migratus supports are few neat knobs, namely :expect-results? and :tx-handles-ddl? (which is just neat)
  • Migratus is SQL-specific, while Ragtime is more of a Ring-level abstraction that caters for any datastore that has a schema or otherwise benefits from data migrations (read more on the Concepts page)
  • Because of this Ring-like nature, configuring Ragtime is a bit more involving (60 LoC in my case)
0 votes
by

I haven't used Migratus, but I have been using Ragtime for years on multiple projects, and I haven't encountered any issues so far. It's a simple library with a straightforward concept that is very stable and easy to work with and extend. You can use Ragtime for migrating various types of data, similarly to Migratus, although it only supports SQL databases out of the box. For instance, I have implemented Cassandra migrations using Ragtime in a private project. Additionally, with the ragtime-clj [1] library, you can write migrations using Clojure code [2].

I don't understand Mark's comment about how Ragtime is more involved regarding configuration (maybe I'm missing some advanced things). My typical Ragtime code only requires two calls at application startup: ragtime.repl/migrate and/or ragtime.repl/rollback.

[1] https://github.com/mariusz-jachimowicz-83/ragtime-clj
[2] https://github.com/mariusz-jachimowicz-83/ragtime-clj/blob/master/test/migrations/008_test.clj

...