Search code examples
sequelize.jssequelize-cliumzug

Promise chaining in Sequelize migrations - relation does not exist


This simple test code:

return queryInterface.createTable('tadam', {id: Sequelize.INTEGER, humus: Sequelize.STRING(255)})
      .then(queryInterface.sequelize.query('ALTER TABLE tadam ADD PRIMARY KEY (id)'));

returns the following error:

Unhandled rejection SequelizeDatabaseError: relation "tadam" does not exist

Now, I understand that by the time the second promise (about altering the table) is executed, the table hasn't been created yet.

It could not be because all queries within the migration are executed together at once, because I have, f.e. this test migration:

return queryInterface.sequelize.query('ALTER TABLE tadam DROP CONSTRAINT tadam_pkey')
  .then(queryInterface.removeIndex('tadam', 'tadam_pkey'));

and it works fine.

So, can anyone give explanation why the first one does not work and how can I implement it, so that the creation of the table + adding the PK can be executed from a single migration?


Solution

  • This is a common mistake when chaining promises that need to execute in series. You're passing queryInterface.sequelize.query('ALTER TABLE tadam ADD PRIMARY KEY (id)') directly to then(), meaning it will run straight away (i.e. before the table has been created, because the first promise won't have finished yet).

    You need return the promise from a function, like so:

    return queryInterface.createTable('tadam', {id: Sequelize.INTEGER, humus: Sequelize.STRING(255)})
      .then(function(results) {
        // results will be the result of the first query
        return queryInterface.sequelize.query('ALTER TABLE tadam ADD PRIMARY KEY (id)');
      });