web-dev-qa-db-fra.com

Comment ajouter, supprimer de nouvelles colonnes dans Sequelize CLI

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."

27
Gijo Varghese

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
50

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/

15
thedanotto

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'
    );
  }
}

Ce qui fournira intellisense comme ci-dessous sequelize intellisense

2
NS23

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;
        }
    }
};
0
Tim Newton