Sling Academy
Home/Node.js/How to Get a Flat Object from Sequelize with Association

How to Get a Flat Object from Sequelize with Association

Last updated: December 29, 2023

Overview

Sequelize is a powerful Object-Relational Mapping (ORM) library for Node.js. It allows developers to work with relational databases like MySQL, PostgreSQL, and SQLite in an object-oriented fashion. One common requirement is to retrieve data from linked tables as a flat object, which can be simpler to work with than nested representations. This tutorial will guide you through the process of flattening associated data using Sequelize.

Basic Flat Query

To start, we will fetch data from a primary table with a simple association. Consider a model User which has a one-to-one relationship with a Profile model. Using Sequelize’s include option, we can easily fetch the associated data. However, by default, Sequelize nests the result:

User.findOne({
  include: [
    {
      model: Profile,
      as: 'profile',
    },
  ],
}).then(user => {
  console.log(user);
});

To flatten this object, we can use Sequelize’s attributes functionality to specify the fields we want and concatenate them with the fields from the main User model:

User.findOne({
  attributes: [
    'id', 'username', [Sequelize.col('profile.bio'), 'bio'],
  ],
  include: [
    {
      model: Profile,
      attributes: [],
    },
  ],
}).then(user => {
  console.log(user.get({ plain: true }));
});

Advanced Flat Query Techniques

When dealing with more complex associations, such as a many-to-many relationship, we may want to include specific attributes from the join table or apply aggregations. Here’s an advanced example:

User.findAll({
  attributes: {
    include: [
      [Sequelize.literal('(`roles->UserRole`.role_id)`'), 'roleId'],
    ],
  },
  include: [
    {
      model: Role,
      through: { attributes: [] },
      attributes: [],
    },
  ],
}).then(users => {
  users.forEach(user => {
    console.log(user.get({ plain: true }));
  });
});

In this example, we have purposefully excluded attributes from the associated Role model and the join table UserRole, but we have manually included the role_id from the join table in our main result set.

Conclusion

Flattening object results with associations in Sequelize requires a good understanding of the library’s querying capabilities. This tutorial has shown you how to get started with basic flattening and move on to more advanced techniques. Always test your queries thoroughly to ensure they meet your application’s requirements and performance goals.

Next Article: Fixing Sequelize.js TypeError: Undefined is Not a Function

Previous Article: Sequelize.js: How to Safely Change Model Schema in Production

Series: Sequelize.js Tutorials

Node.js

You May Also Like

  • NestJS: How to create cursor-based pagination (2 examples)
  • Cursor-Based Pagination in SequelizeJS: Practical Examples
  • MongooseJS: Cursor-Based Pagination Examples
  • Node.js: How to get location from IP address (3 approaches)
  • SequelizeJS: How to reset auto-increment ID after deleting records
  • SequelizeJS: Grouping Results by Multiple Columns
  • NestJS: Using Faker.js to populate database (for testing)
  • NodeJS: Search and download images by keyword from Unsplash API
  • NestJS: Generate N random users using Faker.js
  • Sequelize Upsert: How to insert or update a record in one query
  • NodeJS: Declaring types when using dotenv with TypeScript
  • Using ExpressJS and Multer with TypeScript
  • NodeJS: Link to static assets (JS, CSS) in Pug templates
  • NodeJS: How to use mixins in Pug templates
  • NodeJS: Displaying images and links in Pug templates
  • ExpressJS + Pug: How to use loops to render array data
  • ExpressJS: Using MORGAN to Log HTTP Requests
  • NodeJS: Using express-fileupload to simply upload files
  • ExpressJS: How to render JSON in Pug templates