如何在 Sequelize CLI 中添加、删除新列
How to Add, Delete new Columns in Sequelize CLI
我刚刚开始使用 Sequelize 和 Sequelize CLI
由于是开发时期,经常会增删栏目。向现有模型添加新列的最佳方法是什么?
例如,我想将新列'completed'改为Todo模型。我会将此列添加到 models/todo.js。下一步是什么?
我试过了sequelize db:migrate
不工作:"No migrations were executed, database schema was already up to date."
如果您正在使用 sequelize-cli,您需要先创建迁移。这只是一个文件,告诉引擎如何更新数据库以及如何在出现问题时回滚更改。您应该始终将此文件提交到您的存储库
$ sequelize migration:create --name name_of_your_migration
迁移文件如下所示:
module.exports = {
up: function(queryInterface, Sequelize) {
// logic for transforming into the new state
return queryInterface.addColumn(
'Todo',
'completed',
Sequelize.BOOLEAN
);
},
down: function(queryInterface, Sequelize) {
// logic for reverting the changes
return queryInterface.removeColumn(
'Todo',
'completed'
);
}
}
然后,运行它:
$ sequelize db:migrate
如果您想将多个列添加到同一个 table,请将所有内容包装在一个 Promise.all()
中,然后将您要添加的列放在一个数组中:
module.exports = {
up: (queryInterface, Sequelize) => {
return Promise.all([
queryInterface.addColumn(
'tableName',
'columnName1',
{
type: Sequelize.STRING
}
),
queryInterface.addColumn(
'tableName',
'columnName2',
{
type: Sequelize.STRING
}
),
]);
},
down: (queryInterface, Sequelize) => {
return Promise.all([
queryInterface.removeColumn('tableName', 'columnName1'),
queryInterface.removeColumn('tableName', 'columnName2')
]);
}
};
您可以使用 sequelize 支持的任何列类型 https://sequelize.readthedocs.io/en/2.0/api/datatypes/
如果您在vscode工作,您可以在迁移文件中添加类型定义。这有助于识别 QueryInterface 和 sequelize 提供的所有方法。
module.exports = {
/**
* @typedef {import('sequelize').Sequelize} Sequelize
* @typedef {import('sequelize').QueryInterface} QueryInterface
*/
/**
* @param {QueryInterface} queryInterface
* @param {Sequelize} Sequelize
* @returns
*/
up: function(queryInterface, Sequelize) {
// logic for transforming into the new state
return queryInterface.addColumn(
'Todo',
'completed',
Sequelize.BOOLEAN
);
},
down: function(queryInterface, Sequelize) {
// logic for reverting the changes
return queryInterface.removeColumn(
'Todo',
'completed'
);
}
}
这将提供如下所示的智能感知
根据 Pter 在交易中包装 Promise 的建议,这里有一个使用 async/await 和交易的示例(来自创建索引时修复错误的文档):
'use strict';
module.exports = {
async up(queryInterface, Sequelize) {
const transaction = await queryInterface.sequelize.transaction();
try {
await queryInterface.addColumn(
'Todo',
'completed',
{
type: Sequelize.STRING,
},
{ transaction }
);
await queryInterface.addIndex(
'Todo',
{
fields: ['completed'],
unique: true,
},
{ transaction }
);
await transaction.commit();
} catch (err) {
await transaction.rollback();
throw err;
}
},
async down(queryInterface, Sequelize) {
const transaction = await queryInterface.sequelize.transaction();
try {
await queryInterface.removeColumn(
'Todo',
'completed',
{ transaction }
);
await transaction.commit();
} catch (err) {
await transaction.rollback();
throw err;
}
}
};
在 sequelize 中添加多列
步骤 1: 生成空迁移
sequelize migration:generate --name custom_name_describing_your_migration
第 2 步: 向空迁移中添加列
根据文档使用交易 https://sequelize.org/master/manual/migrations.html#migration-skeleton:
module.exports = {
up: (queryInterface, Sequelize) => {
return queryInterface.sequelize.transaction((t) => {
return Promise.all([
queryInterface.addColumn('table_name', 'field_one_name', {
type: Sequelize.STRING
}, { transaction: t }),
queryInterface.addColumn('table_name', 'field_two_name', {
type: Sequelize.STRING,
}, { transaction: t })
])
})
},
down: (queryInterface, Sequelize) => {
return queryInterface.sequelize.transaction((t) => {
return Promise.all([
queryInterface.removeColumn('table_name', 'field_one_name', { transaction: t }),
queryInterface.removeColumn('table_name', 'field_two_name', { transaction: t })
])
})
}
};
步骤 3:运行迁移
sequelize db:migrate
我认为,如果您在添加或删除特定 table 之前检查您的专栏,那就太好了。如果该列已经存在,这将消除错误。
'use strict';
module.exports = {
// result_description
up: async (queryInterface, Sequelize) => {
let tableName = 'yourTableName';
let columnName1 = 'columnName1';
let columnName2 = 'columnName1';
return Promise.all([
queryInterface.describeTable(tableName)
.then(tableDefinition => {
if (tableDefinition.columnName1) return Promise.resolve();
return queryInterface.addColumn(
tableName,
columnName1,
{
type: Sequelize.INTEGER,
allowNull: false
}
);
}),
queryInterface.describeTable(tableName)
.then(tableDefinition => {
if (tableDefinition.columnName2) return Promise.resolve();
return queryInterface.addColumn(
tableName,
columnName2,
{
type: Sequelize.STRING,
allowNull: false
}
);
})
]);
},
down: (queryInterface, Sequelize) => {
let tableName = 'TestList';
let columnName1 = 'totalScore';
let columnName2 = 'resultDescription';
return Promise.all([
queryInterface.describeTable(tableName)
.then(tableDefinition => {
if (tableDefinition.columnName1) return Promise.resolve();
return queryInterface.removeColumn(tableName, columnName1)
}),
queryInterface.describeTable(tableName)
.then(tableDefinition => {
if (tableDefinition.columnName1) return Promise.resolve();
return queryInterface.removeColumn(tableName, columnName2)
}),
]);
}
};
您仍然可以使用 sync 函数,该函数采用带有两个选项的对象参数,当然,一个是您不添加值的默认选项,另一个是您添加强制或更改属性的实例。
所以在这种情况下你想使用 UserModel.sync({ force: true })
:这会创建 table,如果它已经存在则先删除它
UserModel.sync({ alter: true })
这会检查数据库中 table 的当前状态(它有哪些列,它们的数据类型是什么,等等),然后在 table 中执行必要的更改使其与模式相匹配...
您可以在使用模型实例时使用它
有关更新和 tables 和模型的更多信息,请查看有关更多功能的文档 here
我刚刚开始使用 Sequelize 和 Sequelize CLI
由于是开发时期,经常会增删栏目。向现有模型添加新列的最佳方法是什么?
例如,我想将新列'completed'改为Todo模型。我会将此列添加到 models/todo.js。下一步是什么?
我试过了sequelize db:migrate
不工作:"No migrations were executed, database schema was already up to date."
如果您正在使用 sequelize-cli,您需要先创建迁移。这只是一个文件,告诉引擎如何更新数据库以及如何在出现问题时回滚更改。您应该始终将此文件提交到您的存储库
$ sequelize migration:create --name name_of_your_migration
迁移文件如下所示:
module.exports = {
up: function(queryInterface, Sequelize) {
// logic for transforming into the new state
return queryInterface.addColumn(
'Todo',
'completed',
Sequelize.BOOLEAN
);
},
down: function(queryInterface, Sequelize) {
// logic for reverting the changes
return queryInterface.removeColumn(
'Todo',
'completed'
);
}
}
然后,运行它:
$ sequelize db:migrate
如果您想将多个列添加到同一个 table,请将所有内容包装在一个 Promise.all()
中,然后将您要添加的列放在一个数组中:
module.exports = {
up: (queryInterface, Sequelize) => {
return Promise.all([
queryInterface.addColumn(
'tableName',
'columnName1',
{
type: Sequelize.STRING
}
),
queryInterface.addColumn(
'tableName',
'columnName2',
{
type: Sequelize.STRING
}
),
]);
},
down: (queryInterface, Sequelize) => {
return Promise.all([
queryInterface.removeColumn('tableName', 'columnName1'),
queryInterface.removeColumn('tableName', 'columnName2')
]);
}
};
您可以使用 sequelize 支持的任何列类型 https://sequelize.readthedocs.io/en/2.0/api/datatypes/
如果您在vscode工作,您可以在迁移文件中添加类型定义。这有助于识别 QueryInterface 和 sequelize 提供的所有方法。
module.exports = {
/**
* @typedef {import('sequelize').Sequelize} Sequelize
* @typedef {import('sequelize').QueryInterface} QueryInterface
*/
/**
* @param {QueryInterface} queryInterface
* @param {Sequelize} Sequelize
* @returns
*/
up: function(queryInterface, Sequelize) {
// logic for transforming into the new state
return queryInterface.addColumn(
'Todo',
'completed',
Sequelize.BOOLEAN
);
},
down: function(queryInterface, Sequelize) {
// logic for reverting the changes
return queryInterface.removeColumn(
'Todo',
'completed'
);
}
}
这将提供如下所示的智能感知
根据 Pter 在交易中包装 Promise 的建议,这里有一个使用 async/await 和交易的示例(来自创建索引时修复错误的文档):
'use strict';
module.exports = {
async up(queryInterface, Sequelize) {
const transaction = await queryInterface.sequelize.transaction();
try {
await queryInterface.addColumn(
'Todo',
'completed',
{
type: Sequelize.STRING,
},
{ transaction }
);
await queryInterface.addIndex(
'Todo',
{
fields: ['completed'],
unique: true,
},
{ transaction }
);
await transaction.commit();
} catch (err) {
await transaction.rollback();
throw err;
}
},
async down(queryInterface, Sequelize) {
const transaction = await queryInterface.sequelize.transaction();
try {
await queryInterface.removeColumn(
'Todo',
'completed',
{ transaction }
);
await transaction.commit();
} catch (err) {
await transaction.rollback();
throw err;
}
}
};
在 sequelize 中添加多列
步骤 1: 生成空迁移
sequelize migration:generate --name custom_name_describing_your_migration
第 2 步: 向空迁移中添加列
根据文档使用交易 https://sequelize.org/master/manual/migrations.html#migration-skeleton:
module.exports = {
up: (queryInterface, Sequelize) => {
return queryInterface.sequelize.transaction((t) => {
return Promise.all([
queryInterface.addColumn('table_name', 'field_one_name', {
type: Sequelize.STRING
}, { transaction: t }),
queryInterface.addColumn('table_name', 'field_two_name', {
type: Sequelize.STRING,
}, { transaction: t })
])
})
},
down: (queryInterface, Sequelize) => {
return queryInterface.sequelize.transaction((t) => {
return Promise.all([
queryInterface.removeColumn('table_name', 'field_one_name', { transaction: t }),
queryInterface.removeColumn('table_name', 'field_two_name', { transaction: t })
])
})
}
};
步骤 3:运行迁移
sequelize db:migrate
我认为,如果您在添加或删除特定 table 之前检查您的专栏,那就太好了。如果该列已经存在,这将消除错误。
'use strict';
module.exports = {
// result_description
up: async (queryInterface, Sequelize) => {
let tableName = 'yourTableName';
let columnName1 = 'columnName1';
let columnName2 = 'columnName1';
return Promise.all([
queryInterface.describeTable(tableName)
.then(tableDefinition => {
if (tableDefinition.columnName1) return Promise.resolve();
return queryInterface.addColumn(
tableName,
columnName1,
{
type: Sequelize.INTEGER,
allowNull: false
}
);
}),
queryInterface.describeTable(tableName)
.then(tableDefinition => {
if (tableDefinition.columnName2) return Promise.resolve();
return queryInterface.addColumn(
tableName,
columnName2,
{
type: Sequelize.STRING,
allowNull: false
}
);
})
]);
},
down: (queryInterface, Sequelize) => {
let tableName = 'TestList';
let columnName1 = 'totalScore';
let columnName2 = 'resultDescription';
return Promise.all([
queryInterface.describeTable(tableName)
.then(tableDefinition => {
if (tableDefinition.columnName1) return Promise.resolve();
return queryInterface.removeColumn(tableName, columnName1)
}),
queryInterface.describeTable(tableName)
.then(tableDefinition => {
if (tableDefinition.columnName1) return Promise.resolve();
return queryInterface.removeColumn(tableName, columnName2)
}),
]);
}
};
您仍然可以使用 sync 函数,该函数采用带有两个选项的对象参数,当然,一个是您不添加值的默认选项,另一个是您添加强制或更改属性的实例。
所以在这种情况下你想使用 UserModel.sync({ force: true })
:这会创建 table,如果它已经存在则先删除它
UserModel.sync({ alter: true })
这会检查数据库中 table 的当前状态(它有哪些列,它们的数据类型是什么,等等),然后在 table 中执行必要的更改使其与模式相匹配... 您可以在使用模型实例时使用它 有关更新和 tables 和模型的更多信息,请查看有关更多功能的文档 here