Search code examples
node.jssequelize.jsumzug

Sequelize umzug migrations


I am using sequelize js and developed a node js application, which is deployed to production and have live DB.

while in development mode, if I need to alter the DB, I used to do it using Sequelize.sync({ force: true }) and it worked well.

But now, after development is done I want to alter a table and add a column to it.

I searched many posts but, didn't get an exact example on how to run these migrations.

I tried to use Umzug and run a migration, but it is throwing me errors.

Here is the code I tried,

migrations/barmigration.js:

  var Sequelize = require('sequelize');

"use strict";

module.exports = {

    up: function(migration, DataTypes) {
      return [
      migration.addColumn(
        'Bars',
        'PrinterId',
        Sequelize.STRING
      ),
      migration.addColumn(
        'Bars',
        'PrinterStatus',
        Sequelize.STRING
      )]

    },

    down: function(migration, DataTypes) {
        return
         [
            migration.removeColumn('Bars', 'PrinterStatus'),
            migration.removeColumn('Bars', 'PrinterId')
        ]
    }

};

Here is the umzug configuration:

 var Umzug = require('umzug');
    var sequelize = require('sequelize');

    var umzug = new Umzug({

        // storage: 'sequelize',
        model: 'Bar',


        storageOptions: {
            sequelize: sequelize,
        },

        migrations: {
            path: './migrations',
            pattern: /\.js$/
        }

    });

    //  umzug.up().then(function(migrations)  {
    //    console.log('Migration complete!');
   //     });

    umzug.down().then(function(migrations)  {
      console.log('Migration complete!');
    });

When I run that file, I am getting an error in up function, at this position return migration.addColumn

Error:

Unhandled rejection TypeError: Cannot read property 'addColumn' of undefined

So, the parameter migration seems to be undefined. Pls help me out.


Solution

  • You need to define the params property inside migrations attribute of the object passed to the constructor of Umzug - it defines the parameters that are passed to the up and down functions. I suppose that the configuration object should be as follows

    {
        storage: 'sequelize',
        storageOptions: {
            sequelize: sequelize // here should be a sequelize instance, not the Sequelize module
        },
        migrations: {
            params: [
                sequelize.getQueryInterface(),
                Sequelize // Sequelize constructor - the required module
            ],
            path: './migrations',
            pattern: /\.js$/
        }
    }
    

    With above definition the migration parameter would now become the sequelize.getQueryInterface(), so simply queryInterface, and the DataTypes parameter is the Sequelize itself.

    The model attribute is used to define a Sequelize migrations model, you do not need to define it if you are satisfied with the default SequelizeMeta table creation. Here is how the Umzug constructor object should look like, and here is how the storageOptions can look like.

    EDIT

    In separate file you need to create a Sequelize instance (further used to define models etc.) and export it. Let's assume files tree as below

     - db
         - database.js
         - umzug.js
    

    So in the database.js we create a Sequelize instance and export it.

     // database.js
     const Sequelize = require('sequelize');
    
     const db = {
         sequelize: new Sequelize(connectionString, options),
         Sequelize: Sequelize
     };
    
     module.exports = db;
    

    Then, in the Umzug configuration file

    // umzug.js
    const db = require('./database');
    
    // here comes the configuration and initialization of Umzug instance with use of db object
    // db.sequelize -> sequelize instance
    // db.Sequelize -> sequelize constructor (class)