sequelize / sequelize-typescript

Decorators and some other features for sequelize
MIT License
2.79k stars 282 forks source link

error when calling `drop` method without passing options #1186

Open EvaLok opened 2 years ago

EvaLok commented 2 years ago

Issue

error when using drop method without passing options (passing an empty options objects works, tho)

Versions

Issue type

Actual behavior

TypeError: Cannot set properties of undefined (setting 'supportsSearchPath')
    at PostgresQueryInterface.dropTable (node_modules/sequelize/lib/dialects/postgres/query-interface.js:237:36)
    at runMicrotasks (<anonymous>)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)
    at async Function.drop (node_modules/sequelize/lib/model.js:1388:12)

when reviewing the source referenced, it seems as if the underlying sequelize postgres method wont accept an undefined options object without giving an error. my guess would be that whatever sequelize-typescript method that is calling the top level sequelize drop method probably just needs to check for the absence of options and send an empty options object in order to address the problem (this even works from the very drop level, but if this is intended behaviour then the options param should be required instead of optional)

..from sequelize source

  /**
   * Since postgres has a special case for enums, we should drop the related
   * enum type within the table and attribute
   *
   * @override
   */
  async dropTable(tableName, options) {
    await super.dropTable(tableName, options);
    const promises = [];
    const instanceTable = this.sequelize.modelManager.getModel(tableName, { attribute: 'tableName' });

    if (!instanceTable) {
      // Do nothing when model is not available
      return;
    }

    const getTableName = (!options || !options.schema || options.schema === 'public' ? '' : `${options.schema}_`) + tableName;

    const keys = Object.keys(instanceTable.rawAttributes);
    const keyLen = keys.length;

    for (let i = 0; i < keyLen; i++) {
      if (instanceTable.rawAttributes[keys[i]].type instanceof DataTypes.ENUM) {
        const sql = this.queryGenerator.pgEnumDrop(getTableName, keys[i]);
        options.supportsSearchPath = false; // <-- it gives an error here if options is undefined
        promises.push(this.sequelize.query(sql, { ...options, raw: true }));
      }
    }

    await Promise.all(promises);
  }
}

Expected behavior

should work without error (current fix is to simply pass an empty options object, eg: Some_Model.drop({}) instead of just Some_Model.drop())

Steps to reproduce

call drop method of a model without including options param (postgres and using an enum type field)

Related code

        // gives error
        await Some_Model.drop(); 

        // works
        await Some_Model.drop({}); 
juanmav commented 1 year ago

I had the same problem, and the proposed fix works.

// doesn't work
await models.sequelize.drop();
// works
await models.sequelize.drop({});