如何以编程方式 运行 续集迁移
How to programmatically run sequelize migrations
sequelize 的文档似乎已过时,因为它们不再支持 运行从 sequelize 本身迁移,而是依赖于 sequelize-cli。是否有如何以编程方式使用 sequeliz-cli 来 运行 最新迁移的示例?所有文档似乎都集中在 shell.
中使用客户端
db.js 似乎具有 db:migrate 的功能,也许我可以包含它。
https://github.com/sequelize/cli/blob/master/lib/tasks/db.js
更新:@phil-court 的 更好。
此处为后人提供原始答案...
我深入研究了 sequelize db:migrate
command 的代码,那里发生的事情已经够多了,恕我直言,simplest/best 方法只是 运行 子进程中的命令。这是我为此使用的代码(作为等待的承诺):
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);
});
这就是我所做的。它尚未经过广泛测试,可能可以进一步优化:
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]}})
}
}
我遇到了完全相同的问题并实施了接受的答案。然而,我 运行 陷入并发问题,同时 运行 将其作为一个单独的进程,尤其是在测试期间。
我觉得这个问题比较老,但它在搜索结果中的排名仍然很高。今天,使用 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 的更多信息
sequelize 的文档似乎已过时,因为它们不再支持 运行从 sequelize 本身迁移,而是依赖于 sequelize-cli。是否有如何以编程方式使用 sequeliz-cli 来 运行 最新迁移的示例?所有文档似乎都集中在 shell.
中使用客户端db.js 似乎具有 db:migrate 的功能,也许我可以包含它。
https://github.com/sequelize/cli/blob/master/lib/tasks/db.js
更新:@phil-court 的
此处为后人提供原始答案...
我深入研究了 sequelize db:migrate
command 的代码,那里发生的事情已经够多了,恕我直言,simplest/best 方法只是 运行 子进程中的命令。这是我为此使用的代码(作为等待的承诺):
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);
});
这就是我所做的。它尚未经过广泛测试,可能可以进一步优化:
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]}})
}
}
我遇到了完全相同的问题并实施了接受的答案。然而,我 运行 陷入并发问题,同时 运行 将其作为一个单独的进程,尤其是在测试期间。
我觉得这个问题比较老,但它在搜索结果中的排名仍然很高。今天,使用 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 的更多信息