Sequelize eager loading explained with examples

Sequelize eager loading is a way to fetch data from multiple tables that have relations between each other.

When you use the eager loading technique, the generated SQL query will have one or more JOIN clauses.

Let’s see an example of Sequelize eager loading in action.

Suppose you have two tables in your database named Users and Invoices as follows:

# Users
+----+-----------+
| id | firstName |
+----+-----------+
|  1 | Nathan    |
|  2 | John      |
+----+-----------+

#Invoices
+----+--------+--------+
| id | amount | userId |
+----+--------+--------+
|  1 |    300 |      1 |
|  2 |    100 |      2 |
+----+--------+--------+

The Invoices table stores the UserId to let viewers know which user is creating the invoice row.

This means each Users row may have one or more Invoices rows.

To fetch data from both tables with one query, you need to define the relationship (or association) between the two tables in Sequelize models.

First, create the model for both tables as shown below:

const Invoice = sequelize.define(
  "Invoice",
  { amount: Sequelize.INTEGER },
  { timestamps: false }
);

const User = sequelize.define(
  "User",
  { firstName: Sequelize.STRING },
  { timestamps: false }
);

Once both models are created, define the correct association between the two models.

In this case, User.hasMany() and Invoice.belongsTo() must be defined so that you can fetch both tables from whichever model you choose to query the data:

User.hasMany(Invoice);
Invoice.belongsTo(User);

Now you just need to query the data from the models.

You need to specify the associated model to the main model using the include option as follows:

const user = await User.findByPk(1, { include: Invoice });

console.log(user.toJSON());

The SQL query generated by the findByPk() method above will be like this:

SELECT
  `User`.`id`,
  `User`.`firstName`,
  `Invoices`.`id` AS `Invoices.id`,
  `Invoices`.`amount` AS `Invoices.amount`,
  `Invoices`.`UserId` AS `Invoices.UserId`
FROM
  `Users` AS `User`
  LEFT OUTER JOIN `Invoices` AS `Invoices` 
    ON `User`.`id` = `Invoices`.`UserId`
WHERE
  `User`.`id` = 1;

Here’s the output of the console log above:

{
  id: 1,
  firstName: 'Nathan',
  Invoices: [
    { id: 1, amount: 300, UserId: 1 }
  ]
}

You can also query the User model data from the Invoice model as follows:

const inv = await Invoice.findOne({ where: { amount: 300 }, include: User });

console.log(inv.toJSON());

The output of the findOne() method call above will be like this:

{ 
  id: 1, 
  amount: 300, 
  UserId: 1, 
  User: { 
    id: 1, 
    firstName: 'Nathan' 
  } 
}

And that’s how the eager loading works in Sequelize. It allows you to generate and execute an SQL script that retrieves data from multiple tables at once.

Here’s the complete JavaScript code from model definition to the console log:

const User = sequelize.define(
  "User",
  { firstName: Sequelize.STRING },
  { timestamps: false },
);

const Invoice = sequelize.define(
  "Invoice",
  { amount: Sequelize.INTEGER },
  { timestamps: false },
);

User.hasMany(Invoice);
Invoice.belongsTo(User);

const user = await User.findByPk( 1, { include: Invoice });
console.log(user.toJSON());

const inv = await Invoice.findOne( { where: { amount: 300 }, include: User });
console.log(inv.toJSON());

When you have more than two columns, you can put an array inside the include option of your query method instead of a single Model object:

const user = await User.findByPk(1, { include: [Role, Invoice, /* ... */] });

If you need it, feel free to use the code examples in your JavaScript project. 😉

Take your skills to the next level ⚡️

I'm sending out an occasional email with the latest tutorials on programming, web development, and statistics. Drop your email in the box below and I'll send new stuff straight into your inbox!

No spam. Unsubscribe anytime.