Je viens de commencer à utiliser Sequelize et Sequelize CLI
Comme il s'agit d'une période de développement, les colonnes sont fréquemment ajoutées et supprimées. Quelle est la meilleure méthode pour ajouter une nouvelle colonne à un modèle existant?
Par exemple, je veux une nouvelle colonne 'complété' à Todo modèle. Je vais ajouter cette colonne à models/todo.js. Quelle est la prochaine étape?
J'ai essayé sequelize db:migrate
ne fonctionne pas: "Aucune migration n'a été exécutée, le schéma de base de données était déjà à jour."
Si vous utilisez sequelize-cli , vous devez d'abord créer la migration. Il s'agit simplement d'un fichier qui indique au moteur comment mettre à jour la base de données et comment annuler les modifications en cas de problème. Vous devez toujours valider ce fichier dans votre référentiel
$ sequelize migration:create --name name_of_your_migration
Le fichier de migration ressemblerait à ceci:
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'
);
}
}
Et ensuite, lancez-le:
$ sequelize db:migrate
Si vous souhaitez ajouter plusieurs colonnes à la même table, placez le tout dans un Promise.all()
et placez les colonnes que vous souhaitez ajouter dans un tableau:
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')
]);
}
};
Vous pouvez avoir n'importe quel type de colonne pris en charge par sequelize https://sequelize.readthedocs.io/en/2.0/api/datatypes/
Si vous travaillez en vscode, vous pouvez ajouter une définition de type dans le fichier de migration. ce qui aide à identifier toutes les méthodes fournies par QueryInterface et 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'
);
}
}
Suggestion par Pter d’envelopper Promise dans une transaction, voici un exemple utilisant async/wait et une transaction (à partir de docs avec correction de bogue lors de la création d’un index):
'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;
}
}
};