# Sequelize Node ORM: Promise-Based Node ORM

# Sequelize: Promise-Based Node ORM

Sequelize is a popular, mature Object-Relational Mapping (ORM) library for Node.js that provides a promise-based interface for interacting with relational databases.

## Key Features

### Database Support
- PostgreSQL
- MySQL
- MariaDB
- SQLite
- MSSQL

### Core Capabilities
- **Promise-based API** - Modern async/await support
- **Model definition** - Declarative schema management
- **Associations** - One-to-One, One-to-Many, Many-to-Many relationships
- **Migrations** - Version control for database schema
- **Validation** - Built-in and custom validators
- **Hooks** - Lifecycle callbacks (beforeCreate, afterUpdate, etc.)
- **Query builder** - Fluent interface for complex queries
- **Transactions** - ACID compliance support

## Installation

```bash
npm install sequelize
npm install pg pg-hstore  # PostgreSQL
npm install mysql2        # MySQL
npm install sqlite3       # SQLite
```

## Basic Setup

```javascript
const { Sequelize } = require('sequelize');

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

// Test connection
await sequelize.authenticate();
console.log('Connection established successfully.');
```

## Model Definition

```javascript
const { DataTypes } = require('sequelize');

const User = sequelize.define('User', {
  id: {
    type: DataTypes.INTEGER,
    primaryKey: true,
    autoIncrement: true
  },
  email: {
    type: DataTypes.STRING,
    allowNull: false,
    unique: true,
    validate: {
      isEmail: true
    }
  },
  firstName: {
    type: DataTypes.STRING,
    allowNull: false
  },
  lastName: {
    type: DataTypes.STRING
  },
  age: {
    type: DataTypes.INTEGER,
    validate: {
      min: 0,
      max: 150
    }
  },
  createdAt: {
    type: DataTypes.DATE,
    defaultValue: DataTypes.NOW
  }
}, {
  timestamps: true,
  tableName: 'users'
});
```

## Associations

```javascript
// One-to-Many
User.hasMany(Post, { foreignKey: 'userId' });
Post.belongsTo(User, { foreignKey: 'userId' });

// One-to-One
User.hasOne(Profile, { foreignKey: 'userId' });
Profile.belongsTo(User, { foreignKey: 'userId' });

// Many-to-Many
const UserRole = sequelize.define('UserRole', {}, { timestamps: false });
User.belongsToMany(Role, { through: UserRole });
Role.belongsToMany(User, { through: UserRole });
```

## CRUD Operations

```javascript
// Create
const user = await User.create({
  email: 'john@example.com',
  firstName: 'John',
  lastName: 'Doe',
  age: 30
});

// Read
const user = await User.findByPk(1);
const users = await User.findAll({ where: { age: { [Op.gte]: 18 } } });

// Update
await user.update({ age: 31 });
// or
await User.update({ age: 31 }, { where: { id: 1 } });

// Delete
await user.destroy();
// or
await User.destroy({ where: { id: 1 } });
```

## Query Operations

```javascript
const { Op } = require('sequelize');

// Operators
await User.findAll({
  where: {
    age: { [Op.between]: [18, 65] },
    email: { [Op.like]: '%@gmail.com' },
    status: { [Op.in]: ['active', 'pending'] }
  }
});

// Eager loading
const users = await User.findAll({
  include: [
    { model: Post, as: 'posts' },
    { model: Profile, as: 'profile' }
  ]
});

// Pagination
const users = await User.findAll({
  limit: 10,
  offset: 20,
  order: [['createdAt', 'DESC']]
});
```

## Hooks (Lifecycle Events)

```javascript
User.beforeCreate(async (user) => {
  user.email = user.email.toLowerCase();
});

User.afterCreate(async (user) => {
  console.log(`User ${user.id} created`);
});

User.beforeUpdate(async (user) => {
  user.updatedAt = new Date();
});
```

## Transactions

```javascript
const transaction = await sequelize.transaction();

try {
  await User.create({ email: 'user@example.com' }, { transaction });
  await Post.create({ title: 'Hello', userId: 1 }, { transaction });
  await transaction.commit();
} catch (error) {
  await transaction.rollback();
  throw error;
}
```

## Migrations

```bash
# Generate migration
npx sequelize-cli migration:generate --name create-users-table

# Run migrations
npx sequelize-cli db:migrate

# Undo migration
npx sequelize-cli db:migrate:undo
```

## Advantages

- **Type-safe** - Works well with TypeScript
- **Mature ecosystem** - Well-documented and widely adopted
- **Flexible** - Supports raw queries when needed
- **Validation** - Built-in data validation
- **Relationships** - Intuitive association management

## Disadvantages

- **Learning curve** - Complex for beginners
- **Performance** - Can be slower than raw SQL for complex queries
- **Overhead** - Adds abstraction layer
- **Configuration** - Requires setup and configuration

## Alternatives

- **TypeORM** - Better TypeScript support
- **Prisma** - Modern, type-safe ORM
- **Knex.js** - Query builder (not full ORM)
- **Mikro-ORM** - Lightweight alternative

Sequelize remains a solid choice for Node.js applications requiring robust database abstraction with comprehensive relationship management.
