How to Create Models in Sequelize (JavaScript & TypeScript Examples)

Updated: December 29, 2023 By: Guest Contributor Post a comment

Introduction

Sequelize is a promise-based Node.js ORM for Postgres, MySQL, MariaDB, SQLite, and Microsoft SQL Server. It features solid transaction support, relations, eager and lazy loading, read replication and more. Sequelize follows the paradigm of active record, which allows representing database entries as objects and classes. In this tutorial, we will explore how to define and work with Sequelize models in both JavaScript and TypeScript. Models are the essence of Sequelize, as they represent tables in your database.

Getting Started

Before diving into creating models, make sure that Sequelize is installed in your project:

npm install sequelize
npm install --save-dev sequelize-cli

Additionally, you will need to install the dialect-specific library (e.g., pg for PostgreSQL):

npm install pg pg-hstore

Defining Models in JavaScript

Let’s start by defining a simple model in JavaScript. Assume we’re going to work with a ‘User’ model:

const { Sequelize, Model, DataTypes } = require('sequelize');
const sequelize = new Sequelize('database', 'username', 'password', {
  host: 'localhost',
  dialect: 'mysql'
});

class User extends Model {}

User.init({
  username: DataTypes.STRING,
  birthday: DataTypes.DATE
}, { sequelize, modelName: 'user' });

module.exports = User;

In the code above, we define a User class that extends Sequelize’s Model class. We initialize it with a username and a birthday field, corresponding to columns in the database.

Defining Models in TypeScript

In TypeScript, the process includes typing our models, offering better integration with the TypeScript compiler:

import { Model, DataTypes, Sequelize } from 'sequelize';

const sequelize = new Sequelize('database', 'username', 'password', {
  host: 'localhost',
  dialect: 'mysql'
});

class User extends Model {
  public id!: number; // note the use of '!' as these fields will be populated by Sequelize
  public username!: string;
  public birthday!: Date;
}

User.init({
  id: {
    type: DataTypes.INTEGER.UNSIGNED,
    autoIncrement: true,
    primaryKey: true,
  },
  username: {
    type: new DataTypes.STRING(128),
    allowNull: false,
  },
  birthday: {
    type: DataTypes.DATE,
    allowNull: false,
  },
}, {
  tableName: 'users',
  sequelize: sequelize,
});

export default User;

In TypeScript, each model’s attribute is a class member with typed annotations. The ‘!’ operator is used to tell TypeScript that these fields will exist at runtime, although they are not initialized in the constructor.

Advanced Model Relationships

Sequelize models can have relations such as ‘hasMany’, ‘belongsTo’, ‘belongsToMamy’, and ‘hasOne’. To define a relation, you can extend the basic model definition:

class Project extends Model {}
Project.init({ /* attributes */ }, { sequelize });

class User extends Model {}
User.init({ /* attributes */ }, { sequelize });

// One-To-Many relationship
User.hasMany(Project); // A User can have multiple projects
Project.belongsTo(User); // A Project can only belong to a single user

Such relationships will allow Sequelize to stitch together data from different tables and create more complex queries resembling joins.

Model Synchronization

Once your models are defined, you’ll want to synchronize them with the database.

sequelize.sync({ force: true }).then(() => {
  console.log('Database & tables created!');
});

Be cautious with the ‘force: true’ option, as it will drop existing tables before recreating them, which is useful in development, but dangerous in production.

Conclusion

Creating models in Sequelize is a straightforward process that can be adapted to fit both JavaScript and TypeScript projects. Defining these models is crucial for utilizing the full scope of Sequelize’s ORM capabilities. Throughout this guide, we’ve covered the basic and advanced steps to get you started with Sequelize models, including setup, defining attributes, and establishing relationships between models. Remember to always consider your application’s requirements and adjust your models accordingly to maintain a clean and efficient database structure.