GithubHelp home page GithubHelp logo

rethinkdb-migrate's Introduction

rethinkdb-migrate

Build Status Coverage Status Code Climate Standard - JavaScript Style Guide Dependencies

RethinkDB migration tool

Acknowledgement

This tool is highly inspired by, or, should I say, is a rewrite of, Johan Öbrink's rethink-migrate. Unfortunately, rethink-migrate got stale. This is an attempt to improve the code and tests, track test coverage, update syntax to ES2015 and enhance functionality.

Install

You can either install rethinkdb-migrate globally:

npm install -g rethinkdb-migrate

Or define a npm script for migration and install rethinkdb-migrate locally:

npm install rethinkdb-migrate

In package.json:

{
  "scripts": {
    "migrate": "rethinkdb-migrate"
  }
}

In this last case, rethinkdb-migrate should be run as:

npm run migrate <commands>

All examples will consider that rethinkdb-migrate is installed globally.

Usage

There are currently three operations supported by rethinkdb-migrate:

Operation Command Description
create rethinkdb-migrate create <migration-name> Creates a migration with the given name
up rethinkdb-migrate up Runs all un-executed migrations up
down rethinkdb-migrate down Runs all executed migrations down (unless step option specified)

Create

$ rethinkdb-migrate create <migration name>

This operation creates a migration template file, where the database changes should be made.

The template exports two functions, up and down, that receive an instance of the RethinkDB driver and a connection object. These functions must return a Promise.

Running rethinkdb-migrate create new-migration will create a file YYYYMMDDHHmmss-new-migration.js in the directory ./migrations. Do not change the filename in any way after creating it.

Migrations template:

'use strict'

exports.up = function (r, connection) {
  // must return a Promise!
}

exports.down = function (r, connection) {
  // must return a Promise!
}

Migration example:

'use strict'

exports.up = function (r, connection) {
  return Promise.all([
    r.tableCreate('companies').run(connection),
    r.tableCreate('employees').run(connection)
  ])
}

exports.down = function (r, connection) {
  return Promise.all([
    r.tableDrop('companies').run(connection), r.tableDrop('employees').run(connection)
  ])
}

Up

$ rethinkdb-migrate up --db=mydb

This command will run all pending migrations up, in order of creation. See Options section to configure this task.

Down

$ rethinkdb-migrate down --db=mydb

This command will run all down steps from migrations that have been run previously.

Caution: this refreshes the database to before the first migration (potentially deleting data added since). Be very cautious about running this command in a production environment.

To rollback just a subset of migrations, use the step option:

$ rethinkdb-migrate down --step=2 --db=mydb

See Options section to further configure this task.

Options

The following options can be passed to rethinkdb-migrate:

Option name Default value Description
driver rethinkdb RethinkDB javascript driver. Can be either rethinkdb or rethinkdbdash.
host localhost The host to connect to, if using RethinkDB official driver.
port 28015 The port to connect on, if using RethinkDB official driver.
db None, this is required Database name. Please note that the db will be created if it doesn't already exist, so there is no need to explicitly create it in the migrations.
user '' RethinkDB user
username '' RethinkDB username
password '' RethinkDB password
authKey '' RethinkDB authKey
ssl false RethinkDB SSL/TLS Support. This option can be either true or an options object that will be passed to tls.connect
discovery false Whether or not the driver should try to keep a list of updated hosts. Only available when using rethinkdbdash driver
pool false Whether or not to use a connection pool when using rethinkdbdash driver.
cursor true If true, cursors will not be automatically converted to arrays when using rethinkdbdash.
servers undefined Array of { host, port } of servers to connect to. Only available when using rethinkdbdash
step none Number of migrations to execute or rollback. If omitted, all migrations will be executed or rolled back, potentially refreshing the db to its initial state and resulting in data loss.
migrationsDirectory migrations Directory where migration files will be saved
relativeTo process.cwd() Root path from which migration directory will be searched or created (if inexistent)'
migrationsTable _migrations Table where meta information about migrations will be saved. This should only be changed if you need a _migrations table in your application

Options can be passed to the script in three different ways:

  • Via environment variables
  • Via configuration files
  • Via command line arguments

Command line options take precedence over all other forms of passing options. Configuration file options take precedence over environment variables.

Passing options via environment variables

$ db=mydb rethinkdb-migrate up

Passing options via configuration file

Create a file that exports the options object (can be either a javascript file exporting an object, or a JSON file)

// config.js file

module.exports = {
  db: "mydb",
  driver: "rethinkdbdash",
  pool: true,
  servers: [
    { host: "localhost", port: 28015 },
    { host: "localhost", port: 28016 }
  ],
  ssl: false
}
$ rethinkdb-migrate up -f config.js

Passing options via command line arguments

$ rethinkdb-migrate down --db=mydb --host=127.0.0.1 --port=28016

Contributing

Feel free to suggest improvements and to open PRs. Please add/modify tests to maintain high coverage. Also, code must follow standard style.

Running tests:

In order to run tests, you need three instances of RethinkDB running, two of those should be in a cluster.

To achieve this, do as the following:

  • Install rethinkdb
  • Make sure you have two instances of RethinkDB in a cluster:
$ rethinkdb

# in another terminal session:
$ rethinkdb --port-offset 1 --directory rethinkdb_data2 --join localhost:29015
  • Make sure you have a third instance of rethinkdb running in port 48015:
$ rethinkdb -d rethinkdb_data3 --cluster-port 29017 --no-http-admin --driver-port 48015
  • Clone this repo
  • Make sure you are running node version >= 6
  • npm install
  • npm test

License

MIT License

rethinkdb-migrate's People

Contributors

gibson avatar gristow avatar lirantal avatar pretorh avatar vinicius0026 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

rethinkdb-migrate's Issues

SyntaxError: Unexpected token .

Hey guys,
I'm trying to create migration but got issue with migration JS file. I'm using VSCode and it's underlying . (dot) after r. Also it shows Unexpected Token when I'm trying to run migration.
Does anyone faced that issue? Or have any possible solution?

npm -v: 6:13.4

Migration file:

'use strict'

exports.up = function (r, connection) {
return Promise.all({
r.tableCreate('foo').run(connection),
r.tableCreate('bar').run(connection)
})
}

exports.down = function (r, connection) {
return Promise.all({
r.tableDrop('foo').run(connection),
r.tableDrop('bar').run(connection)
})
}

Stack trace:

rethinkdb-migrate up --step=1 -f config.json

Connecting to RethinkDB
Executing Migrations
Error while running migrations: C:\Users--\migrationtest\migrations\20191220033654-user_roles.js:5
r.tableCreate('foo').run(connection),
^

SyntaxError: Unexpected token .
at new Script (vm.js:79:7)
at createScript (vm.js:251:10)
at Object.runInThisContext (vm.js:303:10)
at Module._compile (internal/modules/cjs/loader.js:657:28)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:700:10)
at Module.load (internal/modules/cjs/loader.js:599:32)
at tryModuleLoad (internal/modules/cjs/loader.js:538:12)
at Function.Module._load (internal/modules/cjs/loader.js:530:3)
at Module.require (internal/modules/cjs/loader.js:637:17)
at require (internal/modules/cjs/helpers.js:22:18)
at migrations.map.migration (C:\Users-\AppData\Roaming\npm\node_modules\rethinkdb-migrate\lib\migrate.js:300:75)
at Array.map ()
at loadMigrationsCode (C:\Users-\AppData\Roaming\npm\node_modules\rethinkdb-migrate\lib\migrate.js:300:21)
at getMigrationsFromPath.then.then.then.migrations (C:\Users-\AppData\Roaming\npm\node_modules\rethinkdb-migrate\lib\migrate.js:276:25)

Completed migrations not saved if later migration fails

Running rethinkdb-migrate up, if there are multiple migrations to execute and any of them fail, the first ones that were successfully executed are not saved to the _migrations table. (Presumably the same is true of rethinkdb-migrate down.)

I'm mainly leaving this here as a note to myself to patch & write tests for this.

Impossible to migrate

Good evening ! x)

I'm trying to migrate a table but i get this error

Do you have any idea how can i fix this please ?

Here my migration.js who contain my configuration... (i will rename this when that's going to work correctly ^^)

module.exports = { db: "qwirk", driver: "rethinkdb", pool: true, servers: [ { host: "localhost", port: 28015 } ], ssl: false }

exports.up = function (r, connection) {
return Promise.all([
r.tableCreate('users').run(connection)
])
}

exports.down = function (r, connection) {
return Promise.all([
r.tableDrop('users').run(connection)
])
}
error_thinkdb

and i tried this : npm run migrate up -f config/migration.js

Migration does not work with rethinkdbdash driver and port different than default

Hi,
When the driver used is rethinkdbdash with a port other than the default (28015), the tool does not work well and tries to run the migrations on a DB using port 28015 in the connection.
This occurs with the following config.js for example:
module.exports = {
db: 'test',
driver: 'rethinkdbdash',
pool: true,
servers: [
{
host: 'localhost',
port: 48015
}
]
}

The issue looks to be in function connectToRethink. When using rethinkdbdash with pool there is no need to do r.connect(...) since rethinkdbdash has a connection pool and manage all the connections itself.

Doesn't run old migration

Say you have two people working on an app, both in a separate branch. (branch-a and branch-b) First the person on branch-b creates a migration to develop their feature, then the person on branch-a.

Now branch-a gets merged and the migration from that branch ran in production. Sometime later branch-b is merged, but the issue is that the branch-b migration doesn't run production, I assume because it's "older" than the last one that was ran from branch-a.

Any ideas how to fix this?

Script finished but doesn't exit

The migration script runs successfully, but does not exists after completion.

Parameters used:

{
  "db": "db_name",
  "driver": "rethinkdbdash",
  "pool": true,
  "cursor": false
}

Remove migration

It'd be great to be able to remove migrations! For example:

rethinkdb-migrate create seed
# Oh wait, I actually don't want that...
rethinkdb-migrate remove seed

Support rethinkdbdash's `ssl` option on each server.

rethinkdbdash supports both of the following config schemas:

{
    db: "some_db",
    pool: true,
    servers: [{
        host: "localhost",
        port: 28015,
        ssl: {
            rejectUnauthorized: false,
        }
    }]
}

and

{
    db: "some_db",
    pool: true,
    servers: [{
        host: "localhost",
        port: 28015,
    }],
    ssl: {
        rejectUnauthorized: false,
    }
}

But only the later is supported by rethinkdb-migrate in its validation of the configuration. This is easy enough to workaround but looks like a small validation oversight in rethinkdb-migrate and ideally we'd pass the same config to rethinkdbdash and rethinkdb-migrate.

Add interpreter option to allow TypeScript, modules, etc...

I'm wondering about the possibility of adding a --interpreter argument, specifying the absolute path to the interpreter, to allow use of, say, ts-node for executing migrations. In the project I work on that uses rethinkdb, we've been steadily converting to TypeScript, and migrations are one of the last areas where we're stuck with .js.

We might possibly also need to add an --extensions argument.

Does this seem of value?

Fix docs

Fix docs as per last PR accepted, as host and port are passed to rethinkdbdash if no pool is being used.

Migration scripts handling errors

Vinicius I'll open up with a big thanks for working out a newly maintained module for handling rethinkdb migrations.

I'm new to rethinkdb and want to bring up an issue - if a migration script attempts to create a database to ensure it exists then the promise is rejected obviously, but I suspect this happens because the rethinkdb-migrate tool itself triggers the db migration when populating the _migrations table.

I came up with the following work-around in my migration script:

'use strict'

exports.up = function (r, connection) {
  return new Promise((resolve, reject) => {
    r.dbCreate('some_db_name').run()
      .then(() => resolve())
      .catch((e) => {
        if (e.message.indexOf('already exists') !== false) {
          resolve()
        } else {
          reject(e)
        }
      })
  })
}

exports.down = function (r, connection) {
  // must return a Promise!
}

I wanted to share and see if it's just me, a known concern or there's generally a better pattern for this.

Running only a single migration?

Maybe this is already possible, just not documented, but it'd be awesome to be able to run a single migration based on the name it was created as:

# Only run seed migration up
rethinkdb-migrate up seed

# Only run staging migration down
rethinkdb-migrate down staging

Even better if that had glob support:

# Run all migrations starting with "seed" up
rethinkdb-migrate up 'seed*'

Remove rethinkdb_data from repo

rethinkdb_data, rethinkdb_data2 and rethinkdb_data3 directories were mistakenly committed to the repo.

Should be removed.

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.