Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to programmatically run sequelize migrations

The documentation for sequelize seems out of date as they no longer support running migrations from sequelize itself, but instead relies on sequelize-cli. Is there an example of how to use sequeliz-cli programmatically to run the latest migrations? All the documentation seems to be focused on using the client in a shell.

db.js seems to have the function db:migrate that perhaps I can include.

https://github.com/sequelize/cli/blob/master/lib/tasks/db.js

like image 729
MonkeyBonkey Avatar asked Jun 15 '15 15:06

MonkeyBonkey


People also ask

How do I run migration in node JS?

Creating Migrations To create a migration, execute db-migrate create with a title. node-db-migrate will create a node module within ./migrations/ which contains the following two exports: exports. up = function (db, callback) { callback(); }; exports.


2 Answers

Update: @phil-court's solution is better.

Original answer here for posterity...


I dug into the code for the sequelize db:migrate command, and there's enough going on there that, IMHO, the simplest/best approach is to just run the command in a child process. Here's the code I used for this (as an await'ed Promise):

const {exec} = require('child_process');

await new Promise((resolve, reject) => {
  const migrate = exec(
    'sequelize db:migrate',
    {env: process.env},
    err => (err ? reject(err): resolve())
  );

  // Forward stdout+stderr to this process
  migrate.stdout.pipe(process.stdout);
  migrate.stderr.pipe(process.stderr);
});
like image 173
broofa Avatar answered Sep 20 '22 07:09

broofa


I had this exact same problem and implemented the accepted answer. However I ran into concurrency issues while running this as a separate process, especially during tests.

I think this question is rather old, but it still appears very high on search results. Today it's a much better idea to run it using umzug. It's the library that sequelize uses to manage migrations on it's end, and is suggested by the docs.

const fs = require('fs');
const Umzug = require('umzug');
const path = require('path');
const Sequelize = require('sequelize');
const { sequelize } = require('../models/index.js');

const umzug = new Umzug({
  migrations: {
    // indicates the folder containing the migration .js files
    path: path.join(process.cwd(), './migrations'),
    // inject sequelize's QueryInterface in the migrations
    params: [
      sequelize.getQueryInterface(),
      Sequelize,
    ],
  },
  // indicates that the migration data should be store in the database
  // itself through sequelize. The default configuration creates a table
  // named `SequelizeMeta`.
  storage: 'sequelize',
  storageOptions: {
    sequelize,
  },
});

async function migrate() {
  return umzug.up();
}

async function revert() {
  return umzug.down({ to: 0 });

And with that you can do everything you need to do with migrations without resorting to spawning a different process, which opens you to all sorts of race conditions and problems down the line. Read more about how to use umzug with the docs on github

like image 25
Phil Court Avatar answered Sep 20 '22 07:09

Phil Court