Giter Site home page Giter Site logo

migratus's Introduction

Migratus

https://travis-ci.org/yogthos/migratus.svg?branch=master

https://cdn.rawgit.com/yogthos/migratus/master/migrate.png

A general migration framework, with an implementation for database migrations.

Designed to be compatible with a git based work flow where multiple topic branches may exist simultaneously, and be merged into a master branch in unpredictable order.

This is accomplished two ways:

  1. Migration ids are not assumed to be incremented integers. It is recommended that they be timestamps (e.g. ‘20111202091200’).
  2. Migrations are considered for completion independently.

Using a 14 digit timestamp will accommodate migrations granularity to a second, reducing the chance of collisions for a distributed team.

In contrast, using a single global version for a store and incremented integers for migration versions, it is possible for a higher numbered migration to get merged to master and deployed before a lower numbered migration, in which case the lower numbered migration would never get run, unless it is renumbered.

Migratus does not use a single global version for a store. It considers each migration independently, and runs all uncompleted migrations in sorted order.

Quick Start

  • add the Migratus dependency:

http://clojars.org/migratus/latest-version.svg

  • Add the following code to resources/migrations/20111206154000-create-foo-table.up.sql
    CREATE TABLE IF NOT EXISTS foo(id BIGINT);
        
  • Add the following code to resources/migrations/20111206154000-create-foo-table.down.sql
    DROP TABLE IF EXISTS foo;
        

Multiple Statements

If you would like to run multiple statements in your migration, then separate them with --;;. For example:

CREATE TABLE IF NOT EXISTS quux(id bigint, name varchar(255));
--;;
CREATE INDEX quux_name on quux(name);

This is necessary because JDBC does not have a method that allows you to send multiple SQL commands for execution. Migratus will split your commands, and attempt to execute them inside of a transaction.

Note that some databases, such as MySQL, do not support transactional DDL commands. If you’re working with such a database then it will not be able to rollback all the DDL statements that were applied in case a statement fails.

Running Functions in Migrations

Functions inside migrations may need to be additionally wrapped, a PostgreSQL example would look as follows:

DO $func$
  BEGIN
  PERFORM schema_name.function_name('foo', 10);
END;$func$;

Setup

  • Add Migratus as a dependency to your project.clj
    :dependencies [[migratus "0.8.32"]]
        

There are hidden dependencies on slf4j inside migratus, so to avoid errors or silent failures you’ll need to also add

[org.slf4j/slf4j-log4j12 "1.7.9"]

or if you’re using Timbre

[com.fzakaria/slf4j-timbre "0.3.2"]

Next, create a namespace to manage the migrations:

(ns my-migrations
 (:require [migratus.core :as migratus]))
(def config {:store                :database
             :migration-dir        "migrations/"
             :init-script          "init.sql"
             :migration-table-name "foo_bar"
             :db {:classname   "org.h2.Driver"
                  :subprotocol "h2"
                  :subname     "site.db"}})
;initialize the database using the 'init.sql' script
(migratus/init config)
;apply pending migrations
(migratus/migrate config)
;rollback the last migration applied
(migratus/rollback config)
;bring up migrations matching the ids
(migratus/up config 20111206154000)
;bring down migrations matching the ids
(migratus/down config 20111206154000)

Generate migration files

Migratus also provides a convenience function for creating migration files:

(migratus/create config "create-user")

This will result with up/down migration files being created prefixed with the current timestamp, e.g:

20150701134958-create-user.up.sql
20150701134958-create-user.down.sql

Quick Start (Leiningen 2.x)

Migratus provides a Leiningen plugin:

  • Add migratus-lein as a plugin in addition to the Migratus dependency:

http://clojars.org/migratus-lein/latest-version.svg

  • Add the following key and value to your project.clj:
    :migratus {:store :database
               :migration-dir "migrations"
               :db {:classname "com.mysql.jdbc.Driver"
                    :subprotocol "mysql"
                    :subname "//localhost/migratus"
                    :user "root"
                    :password ""}}
        

To apply pending migrations:

  • Run lein migratus migrate

To rollback the last migration that was applied run:

  • Run lein migratus rollback

Then follow the rest of the above instructions.

Configuration

Migratus is configured via a configuration map that you pass in as its first parameter. The :store key describes the type of store against which migrations should be run. All other keys/values in the configuration map are store specific.

Databases

To run migrations against a database use a :store of :database, and specify the database connection configuration in the :db key of the configuration map. This connection information is passed directly to clojure.java.jdbc. For example:

{:store :database
 :migration-dir "migrations"
 :db {:classname "com.mysql.jdbc.Driver"
      :subprotocol "mysql"
      :subname "//localhost/migratus"
      :user "root"
      :password ""}}

or:

{:store :database
 :migration-dir "migrations"
 :db ~(get (System/getenv) "DATABASE_URL")}

The :migration-dir key specifies the directory on the classpath in which to find SQL migration files. Each file should be named with the following pattern “[id]-[name].[direction].sql” where id is a unique integer id (ideally it should be a timestamp) for the migration, name is some human readable description of the migration, and direction is either ‘up’ or ‘down’.

If Migratus is trying to run either the up or down migration and it does not exist, then an Exception will be thrown.

See test/migrations in this repository for an example of how database migrations work.

Modify sql fn

If you want to do some processing of the sql before it gets executed, you can provide a `:modify-sql-fn` in the config data structure to do so. This is intended for use with http://2ndquadrant.com/en/resources/pglogical/ and similar systems, where DDL statements need to be executed via an extension-provided function.

Usage

Migratus can be used programmatically by calling one of the following functions:

FunctionDescription
migratus.core/initRuns a script to nitialize the database, e.g: create a new schema.
migratus.core/createCreate a new migration with the current date.
migratus.core/migrateRun ‘up’ for any migrations that have not been run.
migratus.core/rollbackRun ‘down’ for the last migration that was run.
migratus.core/upRun ‘up’ for the specified migration ids. Will skip any migration that is already up.
migratus.core/downRun ‘down’ for the specified migration ids. Will skip any migration that is already down.
migratus.core/pending-listReturns a list of pending migrations.
migratus.core/migrate-until-just-beforeRun ‘up’ for for any pending migrations which precede the given migration id (good for testing migrations).

See the docstrings of each function for more details.

Migratus can also be used from leiningen if you add it as a plugin dependency.

:plugins [[migratus-lein "0.4.1"]]

And add a configuration :migratus key to your project.clj.

:migratus {:store :database
           :migration-dir "migrations"
           :db {:classname "com.mysql.jdbc.Driver"
                :subprotocol "mysql"
                :subname "//localhost/migratus"
                :user "root"
                :password ""}}

You can then run the following tasks:

TaskDescription
lein migratus create <name>Create a new migration with the current date.
lein migratus migrateRun ‘up’ for any migrations that have not been run.
lein migratus rollbackRun ‘down’ for the last migration that was run.
lein migratus up & idsRun ‘up’ for the specified migration ids. Will skip any migration that is already up.
lein migratus down & idsRun ‘down’ for the specified migration ids. Will skip any migration that is already down.
lein migratus resetRun ‘down’ for all migrations that have been run, and ‘up’ for all migrations.
lein migratus pendingRun ‘pending-list’ to get all pending migrations.

License

Copyright © 2016 Paul Stadig, Dmitri Sotnikov

:

Licensed under the Apache License, Version 2.0.

migratus's People

Contributors

yogthos avatar pjstadig avatar gumpt avatar pupeno avatar josedonizetti avatar ajroetker avatar oubiwann avatar mveytsman avatar samroberton avatar ndrluis avatar carlhoerberg avatar edipofederle avatar jfifield avatar oahner avatar lsnape avatar orendon avatar pbzdyl avatar mullr avatar sagarjauhari avatar orthographic-pedant avatar

Watchers

James Cloos avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.