Как добавить, удалить новые столбцы в Sequelize CLI
Я только начал использовать Sequelize и Sequelize CLI
Поскольку это время разработки, частое добавление и удаление столбцов. Каков наилучший способ добавления нового столбца в существующую модель?
Например, я хочу, чтобы новый столбец был " завершен " для модели Todo. Я добавлю этот столбец в models/todo.js. Следующий шаг?
Я попробовал sequelize db:migrate
не работает: "Никаких миграций не было выполнено, схема базы данных уже обновлена".
Ответы
Ответ 1
Если вы используете 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
Ответ 2
Если вы хотите добавить несколько столбцов в одну таблицу, оберните все в 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/
Ответ 3
Если вы работаете в 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'
);
}
}
Который обеспечит intellisense, как показано ниже
Ответ 4
В соответствии с предложением 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;
}
}
};