sequelize / cli

The Sequelize CLI
MIT License
2.54k stars 525 forks source link

Feature: Output the SQL for the ran operation (--dump-sql) #656

Open OsoianMarcel opened 6 years ago

OsoianMarcel commented 6 years ago

Would be great to have an option that will allow us too see the SQL before sequelize-cli will execute it. Because it's a little tricky to run sequelize-cli on production without checking the SQL output before execution.

--dump-sql option that will output the SQL for the ran operation.

Example: node_modules/.bin/sequelize db:migrate --dump-sql

Inspiration: Doctrine (search for "--dump-sql")

ALiangLiang commented 6 years ago

I think we need to mock or refactor QueryInterface to output the query string instead of execute on migration and seed.

Add dryRun option to QueryInterface and its each methods.

I design a flow to return query string from QueryInterface.[methods] but it cannot execute code to Query.run. If I interrupt on Query.run, It cannot response any result back.

sequelize-cli/src/core/migrator.js:

// ...

export function getMigrator (type, args) {
  return Bluebird.try(() => {
    if (!(helpers.config.configFileExists() || args.url)) {
      helpers.view.error(
        'Cannot find "' + helpers.config.getConfigFile() +
        '". Have you run "sequelize init"?'
      );
      process.exit(1);
    }

    const sequelize = getSequelizeInstance();
    const migrator = new Umzug({
      storage: helpers.umzug.getStorage(type),
      storageOptions: helpers.umzug.getStorageOptions(type, { sequelize }),
      logging: helpers.view.log,
      migrations: {

        // pass options to sequelize.getQueryInterface
        params: [sequelize.getQueryInterface({ dryRun: args.dryRun }), Sequelize],

        path: helpers.path.getPath(type),
        pattern: /\.js$/,
        wrap: fun => {
          if (fun.length === 3) {
            return Bluebird.promisify(fun);
          } else {
            return fun;
          }
        }
      }
    });

//...

sequelize/lib/sequelize.js:

// ...

  getQueryInterface(options) {
    // pass options to QueryInterface constructor
    this.queryInterface = this.queryInterface || new QueryInterface(this, options);
    return this.queryInterface;
  }

// ...

sequelize/lib/query-interface.js:

class QueryInterface {
  constructor(sequelize, options) {
    this.sequelize = sequelize;
    this.QueryGenerator = this.sequelize.dialect.QueryGenerator;
    this.options = _.extend({
      dryRun: false
    }, options || {});
  }

// ...

  renameTable(before, after, options) {
    // Accpet object-scoped options 
    // options => this.options => (default options)
    options = _.extend({
      logging: console.log,
      plain: false,
      raw: false,
      showWarnings: false
    }, this.options, options || {});

    const sql = this.QueryGenerator.renameTableQuery(before, after);
    if (options.dryRun) {
      return sql;
    } else {
      return this.sequelize.query(sql, options);
    }
  }

// ...

BTW. Maybe named --dry-run? I think developers are more familiar with it.

OsoianMarcel commented 5 years ago

@ALiangLiang you are right --dry-run it's a good option name.

ALiangLiang commented 5 years ago

similar #219

frederikhors commented 4 years ago

Please any news on this?

AbrahamMunguia commented 1 year ago

Have this been forgotten?

DanielOverdevestPZH commented 5 months ago

Is community still alive?

WikiRik commented 5 months ago

This is still something we want to work on for the CLI. We've started work on the new CLI in the sequelize repo for v7, but progress has been slower these last months due to the maintainers having other things on their mind atm.