Search code examples
node.jspromisesequelize.jsseedseeding

Scalable seeding for Sequelize with Node.js?


I want to set up a piece of code that resets my whole database and seeds everything.

The problem is that with a few Foreign Key constraints, the seeds need to happen in order, however those seeds that are not dependent should happen at the same time asynchronously.

How can I define these seeds in separate files properly?


Solution

  • The problem comes down to exporting Promises with module.exports.

    When I was requiring a file that returned a Promise directly, the Promise was immediately called.
    I solved the problem by returning functions that return the Promise.

    Resetting DB and seeding

    const Seed = require('../seeds/index');
    
    sequelize.sync({ force: true }).then(() => {
        return Seed();
    }).then(() => {
        // DB reset
    }).catch(err => {
        // Error in one of the seeds, specific error in 'err'
    });
    


    seeds/index.js - Calling the seeds in other files

    const UserSeed = require('./user');
    const BComponentSeed = require('./bcomponent');
    const MaterialSeed = require('./material');
    
    module.exports = function() {
        return Promise.all([ // Returning and thus passing a Promise here
            // Independent seeds first
            UserSeed(),
            BComponentSeed(),
            MaterialSeed(),
        ]).then(() => {
            // More seeds that require IDs from the seeds above
        }).then(() => {
            console.log('********** Successfully seeded db **********');
        });
    }
    


    seeds/user.js - Example of the User seed

    const User = require('../models/user');
    const crypto = require('../globs/crypto');
    
    module.exports = function() {
        return User.bulkCreate([ // Returning and thus passing a Promise here
            {
                email: '[email protected]',
                password: crypto.generateHash('john'),
            },
            {
                email: '[email protected]',
                password: crypto.generateHash('a'),
            },
        ]);
    };
    


    Came up with this while responding to this GitHub issue