Skip to main content

Sequelize

یک ORM برای کار کردن با دیتابیس‌های SQL ای با زبان node.js هست

از دیتابیس‌های زیر پشتیبانی میکند:

  • MySQL
  • PostgresQl
  • MariaDB
  • SQLite
  • DB2
  • Oracle
  • Microsoft SQL Server
  • Snowflake

Start

Installation

sequelize دو ورژن اصلی داره. یکی ۷ و یکی ۶. بعد از ورژن ۷ نحوه‌ی نصب هم متفاوت شده. و باید از core اصلی گرفت. ما اینجا داکیومنت ورژن ۷ رو مینویسیم

npm install @sequelize/core

سپس هر دیتابیسی که درنظر داری روش کار کنی رو باید درایورش رو نصب کنی. دقت کن که اگر الان مثلا روی mysql کار میکنی و بعدا خواستی سویچ کنی روی postgres صرف تغییر درایور و کانفیگ اولیه کافی هست و نیاز نیست دوباره با سینتکس متفاوت بیایم بنویسیم. این خوبی ORM ها هست

با توجه به نوع دیتابیسی که میخوای استفاده کنی درایور متناظرش رو باید نصب کنی:

MySQL
npm install @sequelize/mysql
PostgresQL
npm install @sequelize/postgres
MariaDB
npm install @sequelize/mariadb
SQLite
npm install @sequelize/sqlite3
Microsoft SQL Service
npm install @sequelize/mssql
Oracle
npm install @sequelize/oracle

Config

در اینجا کانفیگ اولیه‌ی دیتابیس و نحوه‌ی اتصال بهش رو آوردیم. توی فایل sequelize.config.js مینویسیم

sequelize.config.js
const { Sequelize } = require("@sequelize/core");

const sequelize = new Sequelize({
dialect: "db_type",
port: port_number,
url: "db_type://username:password@host/db_name",
});

sequelize.sync({ alter: true });
sequelize
.authenticate()
.then(() => console.log("Connected to DB Successfully"))
.catch((error) =>
console.log(`Error while connecting to DB: ${error?.message}`),
);

module.exports = { sequelize };

سپس توی فایل اصلی پروژه صرفا sequelize رو ایمپورت میکنیم

server.js
const { sequelize } = require("./configs/sequelize.config");

در این جا ما باید ۵ تا لاین هایلایت شده رو توضیح بدیم

  • dialect : نوع دیتابیسی هست که میخوایم استفاده بکنیم. برای مثال برای استفاده از mysql باید بزنیم dialect: "mysql" و همینطور برای دیتابیس‌های دیگه قابل تعیین هست

  • port : پورتی هست که دیتابیس روش ران هست. معمولا توی لوکال پورت 3306 هست. حتی اگر زمپ و ... نصب کرده باشه

  • url : شامل چند بخش هست که باید پر بشه

    • db_type : همون چیزی هست که برای dialect نوشتی. یعنی اگه میخوای به mysql وصل بشی باید بزنی : mysql://username:password@host/db_name
    • username: یوزرنیم دیتابیس هست
    • password: پسورد دیتابیسه
    • host: هاستی که روش دیتابیس قرار داره (بدون پورت)
    • db_name: اسم دیتابیس هست
    • نکته: معمولا ساخت دیتابیس رو باید دستی انجام بدیم و با کد نمیشه بهش گفت دیتابیس بسازه (code first) نیست معمولا
  • sequelize.sync : کانفیگ نوع sequelize هست

    • force: true : وقتی این آپشن رو توی sync قرار بدی هست و نیست دیتابیس و همه چیزش رو از اول میسازه. یعنی تیبل مدنظر رو کل دیتاش رو حذف میکنه و از اول میسازه و درخواستت رو بعدش انجام میده
    • alter: true : این آپشن برعکس آپشن force دیتابیس رو حذف نمیکنه همه چیزش رو و روی چیزی که بوده ادامه میده کارشو
  • authenticate : یک query روی دیتابیس برای تست انجام میده که بررسی کنه دیتابیس وصل هست یا نه صرفا

info

معمولا sequelize لاگ میندازه و زیاد مینویسه برای خاموش کردن باید آپشن logging:false رو قرار بدیم :

const sequelize = new Sequelize({
// ...
logging: false,
});

در اینجا یک مثال برای اتصال به دیتابیس mysql که با استفاده از xampp راه اندازی شده داریم که اسم دیتابیس هم nodejs هست:

example
const { Sequelize } = require("@sequelize/core");

const sequelize = new Sequelize({
dialect: "mysql",
port: 3306,
url: "mysql://root:@localhost/nodejs",
logging: false,
});

sequelize.sync({ alter: true });
sequelize
.authenticate()
.then(() => console.log("Connected to DB Successfully"))
.catch((error) =>
console.log(`Error while connecting to DB: ${error?.message}`),
);

module.exports = { sequelize };

Create Model

اینجا نحوه‌ی ساختن یک مدل جدید رو توضیح میدیم

init

توی این نمونه با استفاده از init یک مدل(تیبل) میسازیم

const { Model, DataTypes } = require("@sequelize/core");
const { sequelize } = require("../configs/sequelize.config");

class ModelName extends Model {}

ModelName.init(
{
field1: {
type: DataTypes.STRING,
unique: true,
allowNull: false,
},
field2: {
type: DataTypes.STRING,
allowNull: false,
},
},
{ sequelize: sequelize, modelName: "model-name" },
);

module.exports = { ModelName };

ما باید sequelize که در بخش Configs توضیحش دادم رو باید به مدل مدنظر بدیم. از طرفی modelName که میزنیم خودش تهش s میزاره. برای مثال ما user رو بدیم به عنوان modelName توی دیتابیس users سیو میکنه

برای مثال ما یک مدل برای یوزر داریم به صورت زیر هست :

user.model.js
const { Model, DataTypes } = require("@sequelize/core");
const { sequelize } = require("../configs/sequelize.config");

class UserModel extends Model {}

UserModel.init(
{
username: {
type: DataTypes.STRING,
unique: true,
allowNull: false,
},
password: {
type: DataTypes.STRING,
allowNull: false,
},
fullname: {
type: DataTypes.STRING,
allowNull: true,
},
age: {
type: DataTypes.INTEGER,
allowNull: true,
},
status: {
type: DataTypes.BOOLEAN,
defaultValue: true,
allowNull: false,
},
},
{ sequelize: sequelize, modelName: "user" },
);

module.exports = { UserModel };
info

این دیتابیس به اسم users ذخیره میشه

اگر بخوایم s آخرش نزنه باید توی آپشن‌های یک مدل freezeTableName رو هم برابر true قرار بدیم

UserModel.init(
{
// fields ...
},
{ sequelize: sequelize, modelName: "user", freezeTableName: true },
);

در این نمونه با اسم user ذخیره میکنه تیبل رو

define

در این نمونه با استفاده از sequelize.define یک مدل(تیبل) درست میکنیم

const { DataTypes } = require("@sequelize/core");
const { sequelize } = require("../configs/sequelize.config");

const ModelName = sequelize.define(
"model-name",
{
field1: {
type: DataTypes.STRING,
unique: true,
allowNull: false,
},
field2: {
type: DataTypes.STRING,
allowNull: false,
},
},
{
// other options ...
},
);

module.exports = { ModelName };
  1. ورودی اول: اسم مدل
  2. ورودی دوم: فیلد‌های مدل
  3. ورودی سوم: آپشن‌ها مانند وجود timestamps و فریز کردن اسم مدل و ....

توی این روش دیگه نیازی به کلاس Model نیست و مستقیما از sequelize.define استفاده میکنیم برای ساخت یک مدل(تیبل) همچنین اسم مدل رو توی ورودی اول بهش میدیم که تهش خودش s میزاره

برای مثال برای ساخت یک مدل برای یوزر ها به صورت زیر عمل میکنیم :

user.model.js
const { DataTypes } = require("@sequelize/core");
const { sequelize } = require("../configs/sequelize.config");

const UserModel = sequelize.define(
"user",
{
username: {
type: DataTypes.STRING,
unique: true,
allowNull: false,
},
password: {
type: DataTypes.STRING,
allowNull: false,
},
fullname: {
type: DataTypes.STRING,
allowNull: true,
},
age: {
type: DataTypes.INTEGER,
allowNull: true,
},
status: {
type: DataTypes.BOOLEAN,
defaultValue: true,
allowNull: false,
},
},
{ createdAt: "created" },
);

module.exports = { UserModel };
info

توی بخش آپشن ها (ورودی سوم define) میتونیم برای مثال بزنیم timestamps: false در اینصورت دیگه تایم هارو نگه نمیداره.

یا میتونیم بزنیم createdAt: "created_at" که در اینصورت به جای createdAt با اسم created_at ذخیره میکنه

Insert

برای ریختن دیتا(سطر) داخل یک تیبل ۲ روش اصلی وجود دارد

Insert One

برای ریختن یک سطر داخل یک تیبل از تابع create استفاده میکنیم

await ModelName.create({
// fields ...
});

برای مثال برای ریختن دیتای یک یوزر داخل تیبل یوزر‌ها به صورت زیر عمل میکنیم:

example
const result = await UserModel.create({
username: "amirhossein",
password: "mypass",
});

خروجی result برابر یک آبجکت هست که کلید dataValues دیتایی که برای سطر ساخته شده هست رو نشون میده

یعنی اگر ما سطری که ساخته شده رو دیتاش رو بخوایم بگیریم باید از result.dataValues بگیریمش

result.dataValues
{
"id": 1,
"username": "amirhossein",
"password": "mypass",
"updatedAt": "2026-03-16T17:29:56.090Z",
"createdAt": "2026-03-16T17:29:56.090Z"
}

Insert Many

برای ساختن چند سطر داخل تیبل از bulkCreate استفاده میکنیم

await ModelName.bulkCreate([
{ Row1 },
{ Row2 },
// ...
]);

برای مثال برای ریختن ۲ تا یوزر داخل تیبل کاربران به صورت زیر عمل میکنیم:

example
const result = await UserModel.bulkCreate([
{
username: "amirhossein",
password: "mypass",
},
{
username: "amirhossein2",
password: "otherpass",
},
]);

خروجی result یک آرایه‌ای هست که هر فیلدش باید dataValues رو بگیریم.

example
const newResult = result.map((item) => item.dataValues);

حالا خروجی newResult یک آرایه‌ای از یوزر های ساخته شده هست

newResult
[
{
"id": 1,
"username": "amirhossein",
"password": "mypass",
"createdAt": "2026-03-16T17:37:50.394Z",
"updatedAt": "2026-03-16T17:37:50.394Z"
},
{
"id": 2,
"username": "amirhossein2",
"password": "otherpasss",
"createdAt": "2026-03-16T17:37:50.394Z",
"updatedAt": "2026-03-16T17:37:50.394Z"
}
]

Find Or Create

توی این متد میگرده توی تیبل و درصورتی که پیدا بکنه اون سرچی که کردیم رو اونو برمیگردونه در غیر اینصورت یک سطر جدید میسازه از دیتایی که بهش دادیم و بعدش اونو برمیگردونه

await ModelName.findOrCreate({
where: { condition },
defaults: {
fields,
},
});
  • condition : شرطی هست که باید دنبالش بگرده
  • fields : اگر که با شرطی که دادیم سطرمدنظر رو پیدا نکنه مقادیری که توی بخش defaults دادیم رو insert میکنه

خروجی متد findOrCreate یک آرایه‌ی ۲ عضوی هست. که عضو اول سطر نهایی هست(اگه پیدا کنه مقداری که پیدا کرده رو برمیگردونه و اگرم پیدا نکنه سطری که ساخته رو برمیگردونه) و عضو دوم یک boolean هست که نشون میده سطر جدید ساخته یا نه

اگر عضو دوم خروجی true بود یعنی سطر جدید ساخته و اگر false بود یعنی از قبل وجود داشته(find) کرده

برای مثال برای پیدا کردن یک یوزر و درصورت عدم وجود ساختنش به صورت زیر عمل میکنیم:

const result = await UserModel.findOrCreate({
where: { username: "amirhossein" },
defaults: {
password: "mypass2",
},
});
info

توی defaults من فیلد یوزرنیم رو قرار ندادم. چون خودش میفهمه درصورتی که find نکرد برای create یوزرنیم رو هم قرار بده

{
"username": "amirhossein",
"password": "mypass2"
}

نیازی به قرار دادن username نیست چون خودش میفهمه و میره و از where برمیدارتش

همانطور که گفته شده خروجی result به صورت یک آرایه هست

result
[
{
"id": 1,
"username": "amirhossein",
"password": "mypass",
"createdAt": "2026-03-16T17:43:03.795Z",
"updatedAt": "2026-03-16T17:43:03.795Z"
},
false // false = find, true = create
]

برای مثال در مثال بالا یوزرنیم مدنظر از قبل داخل دیتابیس وجود داشته و برای همین عضو دوم آرایه رو false داده

Fields

تمام متد ها برای ساختن یک سطر آپشنی دارن که مشخص کنیم کدوم فیلد هارو میخوایم ذخیره کنیم تو دیتابیس. برای مثال ما هیچوقت توکن کاربر رو توی دیتابیس ذخیره نمیکنیم. و میتونیم از این آپشن استفاده کنیم و بگیم کدوم فیلد‌هارو ذخیره بکنه

create:

await UserModel.create(
{
username: "amirhossein",
password: "mypass",
},
{ fields: ["username"] }, // فقط فیلد یوزرنیم رو ذخیره میکنه
);

bulkCreate:

await UserModel.bulkCreate(
[
{
username: "amirhossein",
password: "mypass",
},
{
username: "amirhossein2",
password: "newpass",
},
],
{ fields: ["username"] }, // فقط فیلد یوزرنیم رو ذخیره میکنه
);

findOrCreate:

await UserModel.findOrCreate({
where: { username: "amirhossein" },
defaults: {
password: "mypass2",
fullname: "amirhossein abazari",
},
fields: ["fullname"], // فقط فیلد فول‌نیم رو ذخیره میکنه
});

Find

اینجا SELECT از دیتابیس رو میگیم

Find All

برای گرفتن چند سطر از یک تیبل از findAll استفاده میکنیم

await UserModel.findAll();

این کد هم خروجیش رو روش باید مپ بزنیم و dataValues رو برگردونم. اما میتونیم با استفاده از قرار دادن آپشن raw دیگه نیازی به مپ زدن نداشته باشیم

await UserModel.findAll({ raw: true });

خروجی این کد دیگه مقدار اضافه نداره و نیاز به گرفتن dataValues نداره

برای مثال برای گرفتن تمام یوزرهای دیتابیس میتونیم به شکل زیر عمل کنیم:

example
const result = await UserModel.findAll({ raw: true });

و مقدار result نیاز به dataValues و ... نداره و مستقیم تمام سطرهارو برمیگردونه

result
[
{
"id": 1,
"username": "amirhossein",
"password": "mypass",
"fullname": null,
"age": 12,
"status": 1,
"createdAt": "2026-03-16 18:06:26.882000+00",
"updatedAt": "2026-03-16 18:06:26.882000+00"
},
{
"id": 2,
"username": "amirhossein2",
"password": "otherpass",
"fullname": null,
"age": 22,
"status": 1,
"createdAt": "2026-03-16 18:06:26.882000+00",
"updatedAt": "2026-03-16 18:06:26.882000+00"
}
]

Find One

برای پیدا کردن یک سطر استفاده میشه که دقیقا مثل find many هست فقط اولین سطری رو که پیدا میکنه برمیگردونه

await ModelName.findOne({
raw: true,
});

برای مثال برای پیدا کردن یک یوزر با یوزرنیم خاص و پسورد خاص به صورت زیر عمل میکنیم

example
const result = await UserModel.findOne({
raw: true,
where: {
username: "amirhossein3",
password: "newpassword",
},
});

خروجی result هم یوزر پیدا شده هست و درصورتی که چیزی پیدا نکنه null برمیگردونه

result
{
"id": 5,
"username": "amirhossein3",
"password": "newpassword",
"fullname": null,
"age": 22,
"status": 1,
"createdAt": "2026-03-16 22:25:53.000000+00",
"updatedAt": "2026-03-16 22:25:53.000000+00"
}

Find By ID

متد findByPk متدی هست که برای پیدا کردن سطر مدنظر با primary key (pk) اش هست.

ورودی اولش مقدار primary key هست و ورودی دومش آپشن‌هاش

await ModelName.findByPk(primary_key, {
raw: true,
});

برای مثال برای پیدا کردن یوزر با آیدی ۱۱ به صورت زیر عمل میکنیم:

example
const result = await UserModel.findByPk(11, {
raw: true,
});

مقدار خروجی result برابر یوزری هست که پیدا کرده

{
"id": 11,
"username": "amirhossein4",
"password": "nwerpass",
"fullname": null,
"age": 22,
"status": 1,
"createdAt": "2026-03-16 22:25:53.000000+00",
"updatedAt": "2026-03-16 22:25:53.000000+00"
}

Max, Min, Sum, Count

۴ تا متد هست که خروجیشون صرفا یک عبارت هست نه یک سطر

await ModelName.max("column-name");
await ModelName.min("column-name");
await ModelName.sum("column-name");
await ModelName.count("column-name");

خروجی هرکدوم یک عدد یا استرینگ هست

برای مثال برای پیدا کردن میانگین سن کاربران به صورت زیر عمل میکنیم:

const sum = await UserModel.sum("age"); // 78
const count = await UserModel.count("age"); // 4
const avg = sum / count; // 78/4 = 19.5

خروجی sum, count, avg هرکدام یک عدد است

Pagination

برای صفحه بندی و دریافت دیتا به صورت مرحله‌ای هست

به این صورت که ما یک page داریم و یک limit که limit نشان میدهد در هر صفحه چند آیتم نشان‌داده میشود

await ModelName.findAll({
limit: limit,
offset: (page - 1) * limit,
});

برای مثال اگر ما در صفحه‌ی ۱۲ هستیم و در هر صفحه ۵۰ آیتم را نشان میدهیم به صورت زیر عمل میکنیم :

const blogs = await BlogModel.findAll({
limit: 50,
offset: 11 * 50,
});

و خروجی ۵۰ تا بلاگ هست که از آیدی 1 + 50 * 11 شروع میشوند و تا آیدی 12 * 50 ادامه دارد (درصورت عدم حذف بلاگی)

Operators

ما برای پیدا کردن سطرهای مدنظر چندین اوپراتور داریم. برای مثال دنبال کاربرانی هستیم که سنشون از ۲۵ سال بیشتر باشه و ...

const { Op } = require("@sequelize/core");

const result = await UserModel.findAll({
raw: true,
where: {
age: {
[Op.gte]: 18, // greater than equal
},
},
});

Op یک متد از sequelize هست که به معنی operator هست

برخی operator هارو اینجا آودریم:

{
"age": {
[Op.gte]: 18, // age >= 18
[Op.gt]: 18, // age > 18
[Op.lte]: 18, // age <= 18
[Op.lt]: 18, // age < 18
[Op.eq]: 18, // age = 18
[Op.ne]: 18, // age != 18
[Op.in]: [18, 12, 22, 43], // age = 18 or 12 or 22 or 43
[Op.notIn]: [18, 12, 22, 43], // age != 18 and 12 and 22 and 43
[Op.startsWith]: 1, // age = 1...
[Op.notStartsWith]: 1, // age != 1...
[Op.endsWith]: 2, // age = ...2
[Op.notEndsWith]: 2, // age != ...2
[Op.regexp]: "^11", // age = 11...
[Op.notRegexp]: "^21", // age != 21...
}
[Op.or]:{
firstname: "amirhossein",
username: "amirhossein" // firstname or username equals to amirhssein
}
}

برای or کردن بین چند شرط باید از [Op.or] استفاده کرد.

برای مثال من میخوام اول اسمش amir باشه یا آخر فامیلیش a نباشه:

{
[Op.or]: {
firstname: {
[Op.startsWith]: "amir"
},
family:{
[Op.notEndsWith] : "a"
}
},
}

Attributes

مشخص میکند چه فیلد(ستون) هایی رو به عنوان خروجی برگردونیم

await ModelName.findAll({
// findOne or finByPk
raw: true,
attributes: ["column-1", "column-2", "column-3", ...],
});

برای مثال وقتی ما دیتای یک یوزر رو میگیریم فقط آیدیش، یوزرنیم، سن و اسمشو میخوایم

example
const result = await UserModel.findAll({
raw: true,
attributes: ["username", "id", "age"],
});

خروجی result به صورت زیر هست

result
[
{
"username": "amirhossein",
"id": 1,
"age": 12
},
{
"username": "amirhossein2",
"id": 2,
"age": 26
},
{
"username": "amirhossein3",
"id": 5,
"age": 22
},
{
"username": "amirhossein4",
"id": 11,
"age": 22
}
]

exclude:

بعضی وقتا ما مشخص میخوایم بکنیم که چه فیلد‌هایی رو نمیخوایم.

در اینصورت از exclude استفاده میکنیم که اون فیلد هارو بهمون برنمیگردونه

await ModelName.findAll({
raw: true,
attributes: {
exclude: ["column-1", "column-2", "column-3", ...],
},
});

برای مثال ما هنگام گرفتن دیتای یک یوزر ستون‌های token و password رو نمیخوایم:

const result = await UserModel.findAll({
raw: true,
attributes: {
exclude: ["password", "token"],
},
});

خروجی result به صورت زیر هست که شامل password و token نمیشود:

[
{
"id": 1,
"username": "amirhossein",
"fullname": null,
"age": 12,
"status": 1,
"createdAt": "2026-03-16 18:06:26.882000+00",
"updatedAt": "2026-03-16 18:06:26.882000+00"
},
{
"id": 2,
"username": "amirhossein2",
"fullname": null,
"age": 22,
"status": 1,
"createdAt": "2026-03-16 18:06:26.882000+00",
"updatedAt": "2026-03-16 18:06:26.882000+00"
},
{
"id": 5,
"username": "amirhossein3",
"fullname": null,
"age": 22,
"status": 1,
"createdAt": "2026-03-16 22:25:53.000000+00",
"updatedAt": "2026-03-16 22:25:53.000000+00"
},
{
"id": 11,
"username": "amirhossein4",
"fullname": null,
"age": 22,
"status": 1,
"createdAt": "2026-03-16 22:25:53.000000+00",
"updatedAt": "2026-03-16 22:25:53.000000+00"
}
]

Access Other Column

وقتی یک سطر رو داریم میگیریم و میخوایم به یکی از ستون هاش دسترسی داشته باشیم باید از sql.attribute استفاده کنیم

برای مثال من میخوام سطرهایی رو بگیرم که username اشون با fullname اشون برابر باشه

example
const { Op, sql } = require("@sequelize/core");

const result = await UserModel.findAll({
where: {
username: {
[Op.eq]: sql.attribute("fullname"),
},
},
raw: true,
});

خروجی result به صورت زیر هست:

[
{
"id": 1,
"username": "amirhossein",
"password": "mypass",
"fullname": "amirhossein",
"age": 12,
"status": 1,
"createdAt": "2026-03-16 18:06:26.882000+00",
"updatedAt": "2026-03-16 18:06:26.882000+00"
}
]

Order By

نحوه‌ی سورت کردن دیتایی که find میکنیم رو نشون میده

await ModelName.findAll({
order: [
["column-1", "DESC"],
["column-2", "ASC"],
// ...
],
});

ما توی order یک ارایه میدیم که اول بر اساس column-1 سورت میکنه و اگر دوتا سطر فیلد column-1 اشون برابر بود سپس بر اساس column-2 و همینطور ادامه میده

توی آرایه ما یک آرایه دو عضوی میدیم که عضو اول اسم اون فیلد هست که بر اساسش باید سورت کنه و عضو دوم ASC یا DESC هست

info

اگر ما خواستیم فیلدی که بر اساسش سورت میکنه ASC باشه میتونیم آرایه دو عضوی ندیم و مستقیم یک استرینگ بدیم که اسم اون ستون هست که میخوایم ASC سورتش کنه:

await ModelName.findAll({
order: [
["column-1", "DESC"],
"column-2", // ASC
// ...
],
});

توی مثال بالا اول بر اساس column-1 به صورت نزولی سورت میکنه و درصورتی که دوتا فیلد برابر بودن column-2 اونارو بر اساس صعودی سورت میکنه

برای مثال من میخوام ابتدا بر اساس سن به صورت نزولی (DESC) سورت کنه و سپس بر اساس id به صورت صعودی (ASC) :

example
const result = await UserModel.findAll({
order: [["age", "DESC"], "id"],
raw: true,
attributes: ["age", "id", "username"],
});

خروجی result به صورت زیر هست :

result
[
{
"age": 22,
"id": 2,
"username": "amirhossein2"
},
{
"age": 22,
"id": 5,
"username": "amirhossein3"
},
{
"age": 12,
"id": 1,
"username": "amirhossein"
},
{
"age": 1,
"id": 11,
"username": "amirhossein4"
}
]

توی مثال بالا دیده میشه که اول بر اساس age به صورت نزولی مرتب کرده و اون دوتایی که age اشون برابر هست رو بر اساس id به صورت صعودی

Update

نحوه‌ی آپدیت کردن مقادیر یک سطر رو توضیح میدیم

Save & Reload

یک روش برای آپدیت کردن فیلد‌های یک سطر هست.

به این صورت هست که ابتدا ما سطر مدنظر رو find میکنیم سپس بعضی ستون هاشو عوض میکنیم. سپس save میکنیم و بعدش reload

const result = await Modelname.findOne({
where: {
condition,
},
});

result["column-1"] = "new value 1";
result["column-2"] = "new value 2";
// ...

result.save();
result.reload();

درواقع سطر مدنظر رو پیدا میکنیم. تغییرات رو روش اعمال میکنیم. سپس save میکنیم و برای دسترسی به مقدار جدید در ادامه‌ی کد reload میکنیم

برای مثال ما میخواهیم تمام یوزر‌هایی رو که سنشون کمتر از ۱۸ سال هست رو اکانتشون رو غیر فعال کنیم:

example
const users = await UserModel.findAll({
where: {
age: {
[Op.lt]: 18,
},
},
attributes: ["age", "id", "username", "status"],
});
users.forEach((user) => {
user.status = false;
user.save();
user.reload();
});

ما اینجا هر یوزر رو به طور جداگانه باید save و reload بکنیم. کل users رو نمیشه یهو save و reload کرد

خروجی users به صورت زیر هست :

users
[
{
"age": 12,
"id": 1,
"username": "amirhossein",
"status": false
},
{
"age": 1,
"id": 11,
"username": "amirhossein4",
"status": false
}
]

همانطور که مشاهده میشود تمام یوزر هایی رو که سنشون کمتر از ۱۸ هست رو اکانتشون رو غیر فعال کرده (status = false)

info

اگر reload نکنی صرفا توی خطای بعدی ممکنه که آپدیت نباشه وگرنه تغییرات روی دیتابیس اعمال میشه

Row Update

یک روش دیگر برای آپدیت یک سطر این هست که اون سطر رو ابتدا find کنیم و سپس update کنیم و سپس reload

const result = await ModelName.findOne({
where: { condition },
});
result.update({
fileds,
});
result.reload();

درواقع توی این روش اول سطر رو پیدا میکنیم. سپس روی اون سطر تابع update رو کال میکنیم. حال برای دسترسی به دیتای اون سطر در خط های بعدی کد reload میکنیم

برای مثال برای غیر فعال کردن حساب کاربری تمام کاربرانی که زیر ۱۸ سال سن دارن به صورت زیر عمل میکنیم:

example
const users = await UserModel.findAll({
where: {
age: {
[Op.lt]: 18,
},
},
attributes: ["age", "id", "username", "status"],
});
users.forEach((user) => {
user.update({
status: false,
});
user.reload();
});

خروجی کد بالا کاربر ها پس از آپدیت هستن:

users
[
{
"age": 12,
"id": 1,
"username": "amirhossein",
"status": false
},
{
"age": 1,
"id": 11,
"username": "amirhossein4",
"status": false
}
]

Model Update

یک روش برای آپدیت کردن یک سطر هست که به صورت زیر عمل میکنه:

await ModelName.update(
{ fields },
{
where: { conditions },
},
);

برای مثال برای غیر فعال کردن اکانت تمام کاربران زیر ۱۸ سال به صورت زیر عمل میکنیم:

example
const result = await UserModel.update(
{ status: false },
{
where: {
age: {
[Op.lt]: 18,
},
},
},
);

در اینجا تمام کاربران زیر ۱۸ سال رو اکانتشون رو (status) رو غیرفعال میکنیم

خروجی result یک آرایه‌ای است که عضو اولش تعداد سطرهایی که در شرط ما(condition) صدق میکردند و سن کمتر از ۱۸ سال داشتنتد رو نشون میده

Delete

برای حذف یک سطر از تیبل ۳ روش داریم

Destroy Row

توی این روش ابتدا سطر مد نظر رو find میکنیم. سپس اون سطر رو روش تابع destroy رو کال میکنیم

let result = await ModelName.findOne({ condition });
await result.destroy();

برای مثال برای حذف یک کاربر با آیدی مدنظر به صورت زیر عمل میکنیم:

example
let user = await UserModel.findByPk(31);
await user.destroy();

Destroy Model

فرق این destroy با destroy قبلی این هست که قبلی روی سطر پیدا شده کال میشد ولی این روی تیبل

await ModelName.destroy({ where: { condition } });

برای مثال برای حذف تمام کاربران با سن زیر ۱۸ سال به صورت زیر عمل میکنیم:

example
const count = await UserModel.destroy({
where: {
age: {
[Op.lt]: 18,
},
},
});

خروجی count تعداد کاربرانی هست که حذف شدند

Truncate

truncate کل سطر های یک تیبل رو به طور کامل پاک میکنه و بعدش انگار هیچوقت اون سطر ها وجود نداشتن.

اگر ما کل سطرهای یک تیبل رو destroy بکنیم و بعدش یک سطر بسازیم آیدی سطر جدید رو از آخرین آیدی حذف شده به بعد قرار میده ولی اگر truncate بکنیم از آیدی یک شروع میشه.

await ModelName.truncate();

و هیچ خروجی نداره کد بالا و کل تیبل رو به صورت کامل سطر هاشو حذف میکنه

Relations

اینجا ارتباط تیبل ها باهم رو توضیح میدیم. برای مثال یک سطر در تیبل user باید یک سطر دقیقا در تیبل profile داشته باشه

One to One

در اینجا ارتباط یک به یک رو داریم. برای مثال یک کاربر در تیبل users یک پروفایل در تیبل profiles داره

برای اینکار خیلی ساده با استفاده از hasOne ارتباط دو تیبل رو یک به یک میکنیم

ModelName1.hasOne(ModelName2, {
foreignKey: {
name: "column1-from-modelname2",
unique: true,
onDelete: "CASCADE",
},
sourceKey: "column2-from-modelname1",
});
  • درواقع توی این مثال ما میگیم هر سطر از ModelName1 یک سطر درون ModelName2 داره که column1 از مدل ModelName2 اشاره میکنه به column2 از مدل ModelName1

  • CASCADE : اینجا میگیم هروقت سطر ModelName1 حذف شد بیا و سطر متناظر باهاش رو توی ModelName2 هم حذف کن

برای مثال برای ارتباط تیبل یوزر با پروفایل به صورت زیر عمل میکنیم:

const { DataTypes } = require("@sequelize/core");
const { sequelize } = require("../configs/sequelize.config");

const UserModel = sequelize.define("user", {
username: {
type: DataTypes.STRING,
unique: true,
allowNull: false,
},
password: {
type: DataTypes.STRING,
allowNull: false,
},
});

const ProfileModel = sequelize.define("profile", {
name: {
type: DataTypes.STRING,
allowNull: false,
},
lastName: {
type: DataTypes.STRING,
allowNull: true,
},
bio: {
type: DataTypes.TEXT,
allowNull: true,
},
});

UserModel.hasOne(ProfileModel, {
foreignKey: {
name: "userId",
unique: true,
onDelete: "CASCADE",
},
sourceKey: "id",
});

module.exports = { UserModel, ProfileModel };

درواقع توی این مثال ما گفتیم هر user یک profile داره. در تیبل profile یک فیلد به اسم userId به صورت اتوماتیک میسازه که به id توی تیبل user اشاره داره

و بین این دوتا ارتباط یک به یک برقرار میکنه

حالا موقع گرفتن یک یوزر ما میتونیم همراه باهاش پروفایلش رو هم بگیریم و از طرفی موقع ساخت یوزر میتونیم بهش یک پروفایل نسبت بدیم:

const user = await UserModel.create({
username: "am_abazari",
password: "mypass",
});
const profile = await ProfileModel.create({
name: "amirhossein",
lastName: "abazari",
bio: "bikar",
});
await user.setProfile(profile);

اینجا ما پروفایلی که ساختیم رو به یوزر مدنظر ارتباط میدیم

info

شاید سوال بشه که setProfile از کجا اومده؟

درکل وقتی ما بین دو تیبل ارتباط برقرار میکنیم میاد ۲ تابع برامون میسازه. یکی به اسم setModelName و دیگری به اسم getModelName

اونجا که ما تعریف کردیم :

sequelize.define("profile" , {...})

از روی این اسم getProfile و setProfile رو ساخته. اگر ما تعریف میکردیم ("sequelize.define("post برای ما ۲ تابع getPost و setPost رو میساخت

حالا وقتی ما یوزر رو گرفتیم میتونیم همراه باهاش به profile متناظرش هم دسترسی داشته باشیم: به صورت زیر :

const user = await UserModel.findByPk(12);
const userProfile = await user.getProfile();

تابع getProfile هم مثل تابع setProfile توسط sequelize ساخته میشه

یا به صورت زیر: با استفاده از include

const user = await UserModel.findByPk(1, { include: ["profile"] });

خروجی کد بالا به صورت زیر هست:

example
{
"id": 1,
"username": "am_abazari",
"password": "mypass",
"createdAt": "2026-03-16T22:40:23.135Z",
"updatedAt": "2026-03-16T22:40:23.135Z",
"profile": {
"id": 1,
"name": "amirhossein",
"lastName": "abazari",
"bio": "bikar",
"createdAt": "2026-03-16T22:40:23.157Z",
"updatedAt": "2026-03-16T22:40:23.163Z",
"userId": 1
}
}

Ony to Many

در اینجا در رابطه با ارتباط یک به چند صحبت میکنیم. برای مثال یک کاربر میتونه چندین بلاگ داشته باشه

ModelName1.hasMany(ModelName2, {
foreignKey: {
name: "column1-from-modelname2",
onDelete: "CASCADE",
},
sourceKey: "column2-from-modelname1",
});

درواقع در این روش ما میگیم تیبل با اسم ModelName1 میتونه چندین تا سطر داخل ModelName2 مرتبط با خودش داشته باشه. به طوری که ستون‌هایی با اسم column1-from-modelname2 از تیبل ModelName2 به یک ستون به اسم column2-from-modelname1 از تیبل ModelName1 اشاره دارن

برای مثال یک کاربر میتونه چندین بلاگ داشته باشه:

const { DataTypes } = require("@sequelize/core");
const { sequelize } = require("../configs/sequelize.config");

const UserModel = sequelize.define("user", {
username: {
type: DataTypes.STRING,
unique: true,
allowNull: false,
},
password: {
type: DataTypes.STRING,
allowNull: false,
},
});

const BlogModel = sequelize.define("blog", {
title: { type: DataTypes.STRING, allowNull: false },
content: { type: DataTypes.STRING, allowNull: false },
});

UserModel.hasMany(BlogModel, {
foreignKey: {
name: "userId",
onDelete: "CASCADE",
},
sourceKey: "id",
});

module.exports = { UserModel, BlogModel };
  • توی این مثال میگه فیلد userId توی تیبل blogs به id توی تیبل users اشاره داره

  • CASCADE : زمانی که یک یوزر حذف شد تمام بلاگ ها مرتبط بهش هم حذف میشن

برای ست کردن یک بلاگ برای یک یوزر به صورت زیر عمل میکنیم:

const user = await UserModel.findByPk(1);
const newBlog = await BlogModel.create({
title: "salam",
content: "salam salamati miare",
});
await user.setBlogs([newBlog]);

و برای گرفتن بلاگ‌های یک یوزر هم به صورت زیر عمل میکنیم:

با استفاده از getBlogs

getBlogs
const user = await UserModel.findByPk(1);
const blogs = await user.getBlogs();

خروجی blogs آرایه‌ای از بلاگ‌های کاربر هست :

blogs
[
{
"id": 12,
"title": "salam",
"content": "salam salamati miare",
"createdAt": "2026-03-16T23:02:00.323Z",
"updatedAt": "2026-03-16T23:02:00.331Z",
"userId": 1
},
{
"id": 13,
"title": "salam2",
"content": "salam salamati miare2",
"createdAt": "2026-03-16T23:04:17.283Z",
"updatedAt": "2026-03-16T23:04:17.304Z",
"userId": 1
}
]

با استفاده از include

include
const user = await UserModel.findByPk(1, { include: "blogs" });

خروجی user به صورت زیر هست:

user
{
"user": {
"id": 1,
"username": "am_abazari",
"password": "mypass",
"createdAt": "2026-03-16T22:40:23.135Z",
"updatedAt": "2026-03-16T22:40:23.135Z",
"blogs": [
{
"id": 13,
"title": "salam",
"content": "salam salamati miare",
"createdAt": "2026-03-16T23:04:17.283Z",
"updatedAt": "2026-03-16T23:04:17.304Z",
"userId": 1
},
{
"id": 14,
"title": "salam2",
"content": "salam salamati miare2",
"createdAt": "2026-03-16T23:04:26.325Z",
"updatedAt": "2026-03-16T23:04:26.335Z",
"userId": 1
}
]
}
}
info

اینکه تابع getBlogs و setBlogs از کجا اومده و یا include: ["blogs"] از کجا اومده

همشون وابسته به اسمی هست که برای مدل میزاریم. ما مدل بلاگ رو با اسم blog تعریف کردیم. و چون ارتباط یک به چند هست خودش s جمع میزاره

اگر ارتباط یک به یک بود به صورت setBlog, getBlog, include:["blog"] تعریف میشد


پس همه‌ی این اسما وابسته به اسمی هست که ما موقع sequelize.define("name") تعریف میکنیم

طبق اون برای یک به یک ها : getName, setName, includes:["name"] هست

و برای یک به چند ها : getNames, setNames, includes: ["names"] هست

Summary

اینجا یک خلاصه آوردیم از ارتباط ها get, set, includes اشون

One to One

  • Create Relation:
UserModel.hasOne(ProfileModel, {
foreignKey: {
name: "userId",
unique: true,
onDelete: "CASCADE",
},
sourceKey: "id",
});
  • Get Profile
const user = await UserModel.findByPk(1, { includes: ["profile"] });

// -----OR-----

const user = await UserModel.findByPk(1);
const profile = await user.getProfile();
  • Set Profile
const user = await UserModel.findByPk(1);
const profile = await ProfileModel.findByPk(12);

user.setProfile(profile);

One to Many

  • Create Relation:
UserModel.hasMany(BlogModel, {
foreignKey: {
name: "userId",
onDelete: "CASCADE",
},
sourceKey: "id",
});
  • Get Blogs:
const user = await UserModel.findByPk(1, { includes: ["blogs"] });

// -----OR-----

const user = await UserModel.findByPk(1);
const blogs = await user.getBlogs();
  • Set Blogs
const user = await UserModel.findByPk(1);
const blog = await BlogModel.findByPk(12);

const oldBlogs = await user.getBlogs();
user.setBlogs([...oldBlogs, blog]);

توی این روش تمام بلاگ‌های قبلی یوزر رو نگه میداره و بلاگ جدید رو بهش اضافه میکنه