Cli: Allow .sequelizerc to export configuration object

Created on 26 Aug 2014  路  19Comments  路  Source: sequelize/cli

My application's configuration is read from environment variables by a config module. I don't want to duplicate part of the configuration just to use sequelize-cli. Is it possible (or could it be) to allow .sequelizerc to export a configuration object instead of just a path to a JSON file. This would be tremendously helpful.

Most helpful comment

To add a property with object value which would represent config for sequelize

I will expand a bit here, in many project that i have seen, uses some kind of config loader, like: nconf, configs-overload or config-load and etc.

If you use something like sails, convention for config files would be proposed in the same manner - http://sailsjs.org/documentation/anatomy/my-app/config

But, with your current approach, i don't see a way how you would properly define settings for db connection without doing some kind of weird hacks above, or define configuration in two places.

All 19 comments

Not sure if I entirely understand the issue. Can you be more concrete about what the .sequelizerc should do and how it should look like?

Please note that the sequelizerc file gets required internally. That basically means, that you can use just nodejs in it.

I think what I was asking is: In the example below, can module.exports.config _be_ the configuration object, or must it be a string _pointing to_ a JSON file?

I'd really like to have my .sequelizerc look something like this:

var path = require('path');

module.exports = {
  'config': {
    dialect: 'mysql',
    database: 'database_name',
    username: 'username',
    password: 'password',
    port: 3306
  },
  'migrations-path': path.resolve('db', 'migrate')
};

Ah. Now I understand. Yes it has to point to a configuration file. What you could try is to point just to the same file and to add the stuff to that file, you would usually have in the config/config.json... Not sure if this is a good approach, though. Actually I'm sure that it is not :D

I don't have configuration in a config file; it is read from process.env. Instead of an object literal (as above), I would actually be constructing the correct object from the environment.

I want to use Sequelize, but this is a deal-breaker. I'm not going to specify my configuration multiple times across multiple files. Maybe .sequelizerc could allow module.exports.config to be either a string or config object?

You can fix your problem by using the following (or a similar) code in the .sequelizerc:

module.exports = {
  "migrations-path": "db/migrations",
  "config": __filename,
  "development": {
    "dialect": "sqlite",
    "storage": "db/development.sqlite"
  }
}

The actual trick is the config property which just states to the very same file, which will make the cli look into it rather than into config/config.json. Please note that the generated models/index.js will try to lookup the provided environment in the exported object and expects in there the respective database credentials and connection settings.

Clever trick. I'll have to try this for my next project.

I'm closing this with the assumption that it works for what I need.

Here is .sequelizerc one I created for a project to pull from a centralized config:

var config = require('./config');

var dbConfig =  JSON.parse('{ "' + config.environment + '" : ' +
                                '{ ' +
                                   '"username": \"' + config.database.username + '", ' +
                                   '"password": "' + config.database.password + '", ' +
                                   '"database": "' + config.database.name + '", ' +
                                   '"host": "' + config.database.host + '", ' +
                                   '"dialect": "' + config.database.dialect + '" ' +
                                '}' +
                           '}');

dbConfig.config = __filename,
dbConfig["migrationsPath"] = "migrations",

module.exports = dbConfig;

The index.js file in the config directory looks like this:

var nconf = require('nconf'); //used to manage config settings per environment
exports.environment = process.env.NODE_ENV || 'development';

nconf.argv()
     .env()
     .file({ file: './config/' + exports.environment + '.json' })
;

//Database configuration settings
exports.database = {
    username: nconf.get('database:username'),
    password: nconf.get('database:password'),
    name: nconf.get('database:name'),
    host: nconf.get('database:host'),
    dialect: nconf.get('database:dialect')    
}

And then there would be an [environment].json file like development.json in the same directory like:

{
    "database": {
        "username": "myapp",
        "password": "myappspassword",
        "name": "mydb",
        "host": "127.0.0.1",
        "dialect": "mysql"
    }
}

It is unfortunate that you have to use some hacks in order to load config in orthodoxical way :/.

Would you accept pull request for changing this?

To change it to what?

To add a property with object value which would represent config for sequelize

I will expand a bit here, in many project that i have seen, uses some kind of config loader, like: nconf, configs-overload or config-load and etc.

If you use something like sails, convention for config files would be proposed in the same manner - http://sailsjs.org/documentation/anatomy/my-app/config

But, with your current approach, i don't see a way how you would properly define settings for db connection without doing some kind of weird hacks above, or define configuration in two places.

I've finally gotten around to needing this again. Here's what I ended up with (in .sequelizerc):

const config = require('./config');

module.exports = {
  config: __filename,

  [config.nodeEnv]: {
    dialect: 'postgres',
    url: config.databaseURL
  }
};

@ravinggenius this causes:

Unknown argument: development

Here is how I fixed my problem:

My ./.env consists of many variables, except that I added this one uniquely for sequelize-cli:

SEQUELIZE_DB_HOST=postgres://user:[email protected]:5432/dbname

And then I created ./sequelize.json:

{
    "development": {
        "use_env_variable": "SEQUELIZE_DB_HOST"
    },

    "test": {
        "use_env_variable": "SEQUELIZE_DB_HOST"
    },

    "production": {
        "use_env_variable": "SEQUELIZE_DB_HOST"
    }
}

And then, finally, in .sequelizerc:

const path = require('path');
require('dotenv').config();

module.exports = {
    'config': path.resolve('./sequelize.json'),
    'models-path': path.resolve('models'),
    'seeders-path': path.resolve('seeders'),
    'migrations-path': path.resolve('migrations'),
}

That's it.


Aside from that, I have config.js that contains a bunch of of config including DB config, and I use that one inside the application. This way config.js DB config only applies to in-app, not in sequelize-cli

Was facing the same issue,
Tried @ravinggenius solution, but it ends up giving the same error Unknown argument: development, just like @MicroDroid pointed out.

For me the configs were partly coming from ENV vars and also from files and I am using Nconf to manage those.

I finally ended up creating a placeholder config.js file, which basically extracts the configs from Nconf and exports them out

const Nconf = require('nconf');
const ConfigHelper = require('../helpers/configHelper');

ConfigHelper.loadConfig(); // This sets up the configs in Nconf. 
const config = Nconf.get('services').mysql;

module.exports = config;

Currently I use the url param inside the rc file, it does do the trick

const path = require('path')
const config = require('./config')

const { host, port, dialect, username, password, name } = config.database

module.exports = {
  'migrations-path': path.resolve('server', 'migrations'),
  'models-path': path.resolve('server', 'models'),
  'seeders-path': path.resolve('server', 'seeders'),
  'url': `${dialect}://${username}:${password}:@${host}:${port}/${name}`
}

this is however for from ideal, @sdepold your solution currently does not work I assume because of the validations inside yargs? Having the possibility to make the rc file work with tools like convict would be a very elegant solution

@klaaz0r I used @shivambarsaley 's technique with convict. The Config import is a standard convict config.js

config/sequelizedb.js

// @flow
import config from 'Config'
const dbConf = config.get('db')
module.exports = dbConf

.sequelizerc

// @flow

require('@babel/register');
const path = require('path');

module.exports = {
  'config': path.resolve('config', 'sequelizedb.js'),
  'models-path': path.resolve('db', 'models'),
  'seeders-path': path.resolve('db', 'seeders'),
  'migrations-path': path.resolve('db', 'migrations')
}

Hello, Is there any way to generate migrations for a multi-tenant application using sequelize cli.

The config.js would have an array of objects that contain the configuration for each database. In my case, there are 18 databases in the multi-tenant application. I want the same migration to take effect in all the databases.

Does anyone have any idea how it could work?

Thats worked for me!

require('dotenv').config();
const path = require('path');

const config = {
  name: process.env.DB_NAME, 
  password: process.env.DB_PASSWORD, 
  username: process.env.DB_USER,
  host: process.env.DB_HOST,
  port: process.env.DB_PORT,
  dialect: process.env.DB_DIALECT
};

module.exports = {
  "models-path": path.resolve('./database/models'),
  "seeders-path": path.resolve('./database/seeders'),
  "migrations-path": path.resolve('./database/migrations'),
  "url": `${config.dialect}://${config.username}:${config.password}:@${config.host}:${config.port}/${config.name}`
};
Was this page helpful?
0 / 5 - 0 ratings