How to programmatically run sequelize migrations

时间:2015-06-15 15:02:10

标签: sequelize.js

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

3 个答案:

答案 0 :(得分:4)

我挖掘了sequelize db:migrate command的代码,并且有足够的进展,恕我直言,最简单/最好的方法是在子进程中运行命令。这是我用于此的代码(作为await'ed Promise):

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

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

  // Forward stdout+stderr to this process
  migrate.stdout.pipe(process.stdout);
  migrate.stderr.pipe(process.stderr);
});

答案 1 :(得分:2)

我遇到了完全相同的问题并实施了已接受的答案。但是,我在将其作为单独的进程运行时遇到了并发问题,尤其是在测试期间。

我觉得这个问题比较老了,但在搜索结果中仍然显得非常高。今天,使用 umzug 运行它是一个更好的主意。 这是 sequelize 用于管理迁移的库,由 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 });

有了它,您可以执行迁移所需的一切操作,而无需求助于生成不同的进程,这会让您面临各种竞争条件和问题。通过 github

上的文档阅读有关如何使用 umzug 的更多信息

答案 2 :(得分:1)

这就是我所做的。它尚未经过广泛测试,并且可能可以进一步优化:

const Sequelize = require('sequelize');
const db = new Sequelize('main', 'test', 'test', {
dialect: 'sqlite',
// SQLite only
storage: db.db'
});

async function checkForMigrations() {
let migrations = fs.readdirSync(__dirname + '/../migrations');
let completedMigrations = await db.query("SELECT * FROM `SequelizeMeta`", {type: Sequelize.QueryTypes.SELECT});
for (let name in completedMigrations) {
    if (completedMigrations.hasOwnProperty(name)) {
        let index = migrations.indexOf(completedMigrations[name].name);
        if (index !== -1) {
            migrations.splice(index, 1);
        }
    }
}

for(let i = 0, c = migrations.length; i < c; i++){
   let migration = require(__dirname + '/../migrations/' + migrations[i]);
   migration.up(db.queryInterface, Sequelize);
   await db.query("INSERT INTO `SequelizeMeta` VALUES(:name)", {type: Sequelize.QueryTypes.INSERT, replacements: {name: migrations[i]}})
}
}