【问题标题】:Sequelize migration add "IF NOT EXISTS" to addIndex and addColumn续集迁移将“IF NOT EXISTS”添加到 addIndex 和 addColumn
【发布时间】:2017-07-29 08:37:50
【问题描述】:

有没有办法强制 Sequelize.js 将 IF NOT EXISTS 添加到 queryInterface.addColumnqueryInterface.addIndex 方法创建的 Postgres SQL 中?

根据 Postgres Docs,Alter Table Add ColumnCreate Index 支持此功能

我浏览了 Sequelize.js 文档但没有任何运气,我试图通过代码找出 SQL 是如何生成的,但我还没有任何运气。


一点背景,或“为什么”

我正在尝试为现有的 postgres 实例创建迁移策略,并且我目前创建了一个 Sequelize 迁移集,该迁移集从“无”迁移到当前架构。现在我想简单地在我的生产服务器上启动并运行它,所有数据都已经存在,这样下次我创建迁移时,我可以运行它。

所有这些都适用于每个queryInterface.createTable,因为IF NOT EXISTS 是自动添加的。

【问题讨论】:

    标签: postgresql sequelize.js


    【解决方案1】:

    我有一个类似的问题,除了在我的情况下,我只对 addColumn IF NOT EXIST 感兴趣。

    您可以通过使用queryInterface.describeTable 的两步解决方案来实现此目的。 给定表名,该函数将返回包含所有现有列的表定义。如果您需要添加的列不存在,则调用queryInterface.addColumn 函数。

    const tableName = 'your_table_name';
    
    queryInterface.describeTable(tableName)
      .then(tableDefinition => {
        if (tableDefinition.yourColumnName) {
          return Promise.resolve();
        }
    
        return queryInterface.addColumn(
          tableName,
          'your_column_name',
          { type: Sequelize.STRING } // or a different column
        );
      });
    

    【讨论】:

      【解决方案2】:

      addColumn函数来自queryGenerator方法addColumnQuery,它接受三个参数——tablekeydataType。通过使用它们,它会创建一个查询,看起来像这样

      let query = `ALTER TABLE ${quotedTable} ADD COLUMN ${quotedKey} ${definition};`;
      

      因此,如您所见,没有将IF NOT EXISTS 子句添加到查询字符串的选项。不幸的是,addIndex 方法也是如此。但是,您可以使用普通查询来执行一些非典型操作

      queryInterface.sequelize.query(...);
      

      【讨论】:

      • 是的,我发现我自己浏览了 repo 的代码。我正在考虑在 repo 上创建一个 PR 以启用此功能,但是我最终做的是手动更新 SequelizeMeta 以伪造迁移的运行。
      • @Cort3z 你有没有为此做过公关?
      • @Simon 我从来没有这样做过。对我来说是一份一劳永逸的工作。我不太记得了,但我可能已经使用 PSequel 或其他一些数据库管理工具手动更新了我的数据库。
      • @Cort3z 是的,我刚刚完成了一个检查现有索引的原始查询。感谢您的跟进!
      【解决方案3】:

      语句if (!tableDefinition.yourColumnName) 将无法检查列是否存在。 正确的做法是

      return queryInterface.describeTable(tableName).then(tableDefinition => {
                  if (!tableDefinition[columnName]){
                      return queryInterface.addColumn(tableName, columnName, {
                          type: Sequelize.JSON
                      });
                  } else {
                      return Promise.resolve(true);
                  }
              });
      

      【讨论】:

      • 谢谢!正是我需要的
      【解决方案4】:

      一个小的工作示例:

      module.exports = {
        /**
         * @description Up.
         * @param {QueryInterface} queryInterface
         * @return Promise<void>
         */
        up: async (queryInterface) => {
          const tableDefinition =  await queryInterface.describeTable('group');
          const promises = [];
      
          return queryInterface.sequelize.transaction((transaction) => {
            if (!tableDefinition.column1) {
              promises.push(queryInterface.addColumn(
                'group',
                'column1',
                {
                  type: queryInterface.sequelize.Sequelize.STRING,
                  allowNull: true,
                },
                {transaction},
              ));
            }
      
            if (!tableDefinition.oauth2_token_expire_at) {
              promises.push(queryInterface.addColumn(
                'group',
                'column2',
                {
                  type: queryInterface.sequelize.Sequelize.DATE,
                  allowNull: true,
                },
                {transaction},
              ));
            }
      
            return Promise.all(promises);
          });
        },
        /**
         * @description Down.
         * @param {QueryInterface} queryInterface
         * @return Promise<void>
         */
        down: (queryInterface) => {
          ...
        },
      };
      
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-05-09
        • 2012-09-12
        • 1970-01-01
        • 2020-10-23
        • 1970-01-01
        • 2020-11-09
        相关资源
        最近更新 更多