Sequelize is a promise-based Node.js ORM (Object-Relational Mapping) for Postgres, MySQL, MariaDB, SQLite, and Microsoft SQL Server. It features solid transaction support, relations, read replication, and more. This guide will walk you through setting up Sequelize in your Node.js application, defining models, performing CRUD operations, and best practices.
Before diving into Sequelize, ensure you have the following installed:
First, create a new directory for your project and initialize it with npm:
mkdir sequelize-example
cd sequelize-example
npm init -y
Install Sequelize along with the appropriate database driver. For this example, we'll use PostgreSQL:
npm install sequelize pg pg-hstore
For other databases, refer to the Sequelize documentation.
Create a file named db.js in your project root and set up a Sequelize instance:
// db.js
const { Sequelize } = require('sequelize');
const sequelize = new Sequelize('database', 'username', 'password', {
host: 'localhost',
dialect: 'postgres'
});
async function connect() {
try {
await sequelize.authenticate();
console.log('Connection has been established successfully.');
} catch (error) {
console.error('Unable to connect to the database:', error);
}
}
connect();
module.exports = sequelize;
Replace 'database', 'username', and 'password' with your actual database credentials.
Sequelize uses models to represent tables in your database. Define a model by extending Model and using sequelize.define():
// models/User.js
const { Model, DataTypes } = require('sequelize');
const sequelize = require('../db');
class User extends Model {}
User.init({
firstName: {
type: DataTypes.STRING,
allowNull: false
},
lastName: {
type: DataTypes.STRING
},
email: {
type: DataTypes.STRING,
allowNull: false,
unique: true
}
}, {
sequelize,
modelName: 'user'
});
module.exports = User;
DataTypes provides various data types like STRING, INTEGER, etc.allowNull: false ensures the field cannot be null.unique: true enforces uniqueness on the email field.To create a new user, use the create() method:
// index.js
const User = require('./models/User');
async function createUser() {
try {
const user = await User.create({
firstName: 'John',
lastName: 'Doe',
email: 'john.doe@example.com'
});
console.log('User created:', user.toJSON());
} catch (error) {
console.error('Error creating user:', error);
}
}
createUser();
To retrieve users, use the findAll() method:
async function getUsers() {
try {
const users = await User.findAll();
console.log('Users:', users.map(user => user.toJSON()));
} catch (error) {
console.error('Error fetching users:', error);
}
}
getUsers();
To update a user, use the update() method:
async function updateUser() {
try {
const user = await User.findByPk(1); // Assuming user with ID 1 exists
if (user) {
await user.update({ firstName: 'Jane' });
console.log('User updated:', user.toJSON());
} else {
console.log('User not found');
}
} catch (error) {
console.error('Error updating user:', error);
}
}
updateUser();
To delete a user, use the destroy() method:
async function deleteUser() {
try {
const user = await User.findByPk(1); // Assuming user with ID 1 exists
if (user) {
await user.destroy();
console.log('User deleted');
} else {
console.log('User not found');
}
} catch (error) {
console.error('Error deleting user:', error);
}
}
deleteUser();
Sequelize supports various associations like one-to-one, one-to-many, and many-to-many. Here's an example of a one-to-many relationship between User and Post:
// models/Post.js
const { Model, DataTypes } = require('sequelize');
const sequelize = require('../db');
class Post extends Model {}
Post.init({
title: {
type: DataTypes.STRING,
allowNull: false
},
content: {
type: DataTypes.TEXT
}
}, {
sequelize,
modelName: 'post'
});
module.exports = Post;
Define the association in User.js:
// models/User.js
const { Model, DataTypes } = require('sequelize');
const sequelize = require('../db');
const Post = require('./Post');
class User extends Model {}
User.init({
// ... existing fields
}, {
sequelize,
modelName: 'user'
});
User.hasMany(Post, { foreignKey: 'userId' });
Post.belongsTo(User, { foreignKey: 'userId' });
module.exports = User;
async function createPostForUser() {
try {
const user = await User.findByPk(1); // Assuming user with ID 1 exists
if (user) {
const post = await user.createPost({
title: 'My First Post',
content: 'This is the content of my first post.'
});
console.log('Post created:', post.toJSON());
} else {
console.log('User not found');
}
} catch (error) {
console.error('Error creating post:', error);
}
}
createPostForUser();
Use Transactions: For complex operations that involve multiple database calls, use transactions to ensure data integrity.
Validate Data: Use Sequelize's built-in validation features to validate data before saving it to the database.
Use Hooks: Define hooks like beforeCreate, afterUpdate to perform actions at specific points in the lifecycle of a model instance.
Separate Concerns: Keep your models, controllers, and services separate for better maintainability.
Environment Variables: Store sensitive information like database credentials in environment variables.
Error Handling: Always handle errors gracefully to avoid exposing sensitive information.
Sequelize is a powerful ORM that simplifies database interactions in Node.js applications. By following this guide, you should have a solid understanding of how to set up Sequelize, define models, and perform CRUD operations. As you become more comfortable with Sequelize, explore its advanced features like scopes, eager and lazy loading, and more complex associations.
For further reading, refer to the Sequelize documentation and check out community resources for additional examples and best practices.