Upgrading to V7 - Multiple NoSQL Databases

Feature(s) impacted

After I upgraded my project to V7 (following the docs here), I got everything up and running in all my environments with no problems. However, today I had to make some changes in order to include another database in my project. Hence, I followed the instructions here, but I got lost when dealing with some files that were created/modified during the upgrade to V7.

Observed behavior

For now, my /middlewares/forestadmin.js file looks like this:

const chalk = require('chalk');
const Liana = require('forest-express-mongoose');
// 1. this was added when following instructions to upgrade to V7, but it seems
// that I don't need it anymore (at least regarding 'connections')
const { objectMapping, connections } = require('../models');
const db1 = require('../models/db1/connection');
const db2 = require('../models/db2/connection');

module.exports = async function forestadmin(app) {
  app.use(await Liana.init({    
    envSecret: process.env.FOREST_ENV_SECRET,
    authSecret: process.env.FOREST_AUTH_SECRET,
    objectMapping, // 2. should I ignore this?
    connections: [  // 3. this was changed to include connections to both databases
      db1,
      db2
    ]
  }));

  console.log(chalk.cyan('Your admin panel is available...'));
};

As you can see, the objectMapping used to be imported from /models/index.js. But since I’m using two databases now, I no longer have the index.js file because my folder architecture became like this:

models/
β”œβ”€β”€ db1/
β”‚   β”œβ”€β”€ connection.js
β”‚   β”œβ”€β”€ model1.js
β”‚   └── model2.js
β”œβ”€β”€ db2/
β”‚   β”œβ”€β”€ connection.js
β”‚   β”œβ”€β”€ model3.js
β”‚   └── model4.js

Just for the record, this is how my models/index.js used to be:

const fs = require('fs');
const path = require('path');
const Mongoose = require('mongoose');

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

const connections = {};
const db = {};

databasesConfiguration.forEach((databaseInfo) => {
  const connection = Mongoose.createConnection(databaseInfo.connection.url, databaseInfo.connection.options);
  connections[databaseInfo.name] = connection;

  const modelsDir = databaseInfo.modelsDir || path.join(__dirname, databaseInfo.name);
  fs
    .readdirSync(modelsDir)
    .filter((file) => file.indexOf('.') !== 0 && file !== 'index.js')
    .forEach((file) => {
      try {
        const model = require(path.join(modelsDir, file))(connection, Mongoose);
        db[model.modelName] = model;
      } catch (error) {
        console.error(`Model creation error: ${error}`);
      }
    });
});

db.objectMapping = Mongoose;
db.connections = connections;

module.exports = db;

Expected behavior

My question is whether I can ignore the objectMapping. If it’s not the case, how should I change /models/db1/connection.js and /models/db2/connection.js to keep my configuration in /middlewares/forestadmin.js as it is?

// => models/db1/connection.js
const mongoose = require('mongoose');
const connection = mongoose.createConnection(process.env.DB1_DATABASE_URL, { useNewUrlParser: true });

module.exports = connection;

Context

  • Package Version: 7.6.0 (forest-express-mongoose)
  • Express Version: 4.17.1
  • Mongoose Version: 5.8.2
  • Project name: parceiros
  • Environment name: all

Thanks in advance and hope you all have a nice end of the year!

Hello @nivea,

I am very sorry, but we seem that this part of the documentation was not properly updated.

While the team works on it, could you please check if this community thread helps with your issue?

Thank you

Hi @nivea :wave: welcome to our community.
Thank you for your feedback.
We apologize about this documentation.

I’m gonna try to help you with some instructions :

  1. remove all connections.js file inside db models.
  2. remove db/connection import from /middlewares/forestadmin.js and use connections from /models
  3. inside config/databases.js add your new database connections informations
{
  name: 'db2',
  modelsDir: path.resolve(__dirname, '../models/db2'),
  connection: {
    url: process.env.DATABASE_URL_2,
    options: { ...databaseOptions },
  },
}
  1. after that you can use forest schema:update from the cli to generate your new models => Update your models' definition - Documentation

Let me know if that help :pray:

Hello @Guillaume_Deslandes and @Arnaud_Moncel ,

Thank you for your feedback. I looked at the community thread that @Guillaume_Deslandes suggested and confirmed I have already settled up correctly the config/databases.js file. All the modifications are addressed in the docs, except for this:

If everything goes well from here, running lumber update should create your missing folders & models for the new database. You will still have to remove previous files located in the models/ folder (except, of course, models/index.js ).

Does it mean I actually didn’t need to remove the models/index.js file that was previously in there?

As for @Arnaud_Moncel suggestion, I followed all steps removing the models/db/connection.js files, as well as the db/connection import, and making sure there are two databases connections in config/databases.js.

Still, in the second step, you mentioned I should use connections from /models. I don’t understand what connections you are talking about, considering I removed all imports related to them. Also, I still have no clue on where I should import the objectMapping from (unless I keep the models/index.js that was previously in there).

confirmed I have already settled up correctly the config/databases.js file

Nice !

You should have the models index that you presented just above.
Next you can run forest schema:update from forest-cli - npm => this should generate all the missing file related to our new database. (eg: models, routes, forest files)

And the middleware should be like this :

const { objectMapping, connections } = require('../models');
...
 app.use(await Liana.init({    
    envSecret: process.env.FOREST_ENV_SECRET,
    authSecret: process.env.FOREST_AUTH_SECRET,
    objectMapping,
    connections,
  }));
...

Let me know.

It works! I brought back the model/index.js file, corrected the imports and everything works smoothly now.

Thank you very much!

1 Like