0
# Model Definition
1
2
Model creation, configuration, and lifecycle management including attributes, validations, scopes, and schema operations.
3
4
## Capabilities
5
6
### Model Initialization
7
8
Initialize a model with attributes and configuration options.
9
10
```typescript { .api }
11
/**
12
* Initialize model with attributes and options
13
* @param attributes - Model attribute definitions
14
* @param options - Model configuration options
15
* @returns The initialized model class
16
*/
17
static init(attributes: ModelAttributes, options: InitOptions): typeof Model;
18
19
interface ModelAttributes {
20
[name: string]: DataType | ModelAttributeColumnOptions;
21
}
22
23
interface ModelAttributeColumnOptions {
24
/** Column data type */
25
type: DataType;
26
/** Allow null values */
27
allowNull?: boolean;
28
/** Default value */
29
defaultValue?: any;
30
/** Primary key column */
31
primaryKey?: boolean;
32
/** Unique constraint */
33
unique?: boolean | string | { name: string; msg?: string };
34
/** Auto increment (integers only) */
35
autoIncrement?: boolean;
36
/** Column comment */
37
comment?: string;
38
/** Custom column name */
39
field?: string;
40
/** Validation rules */
41
validate?: ModelValidateOptions;
42
/** Virtual field getter */
43
get?: () => any;
44
/** Virtual field setter */
45
set?: (value: any) => void;
46
}
47
48
interface InitOptions {
49
/** Sequelize instance */
50
sequelize: Sequelize;
51
/** Model name */
52
modelName?: string;
53
/** Table name */
54
tableName?: string;
55
/** Schema name */
56
schema?: string;
57
/** Enable timestamps (createdAt, updatedAt) */
58
timestamps?: boolean;
59
/** Paranoid mode (soft delete) */
60
paranoid?: boolean;
61
/** Use underscored column names */
62
underscored?: boolean;
63
/** Freeze table name (disable pluralization) */
64
freezeTableName?: boolean;
65
/** Table indexes */
66
indexes?: IndexesOptions[];
67
/** Model hooks */
68
hooks?: Partial<ModelHooks>;
69
/** Model scopes */
70
scopes?: ModelScopeOptions;
71
/** Default scope */
72
defaultScope?: FindOptions;
73
/** Model validation options */
74
validate?: ModelValidateOptions;
75
}
76
```
77
78
**Usage Examples:**
79
80
```typescript
81
import { Model, DataTypes, Sequelize } from "sequelize";
82
83
const sequelize = new Sequelize("sqlite::memory:");
84
85
// Basic model definition
86
class User extends Model {}
87
User.init({
88
firstName: DataTypes.STRING,
89
lastName: DataTypes.STRING,
90
email: DataTypes.STRING
91
}, {
92
sequelize,
93
modelName: 'user'
94
});
95
96
// Advanced model with all options
97
class Product extends Model {
98
public id!: number;
99
public name!: string;
100
public price!: number;
101
public description?: string;
102
public createdAt!: Date;
103
public updatedAt!: Date;
104
}
105
106
Product.init({
107
id: {
108
type: DataTypes.INTEGER,
109
primaryKey: true,
110
autoIncrement: true
111
},
112
name: {
113
type: DataTypes.STRING(100),
114
allowNull: false,
115
unique: true,
116
validate: {
117
len: [3, 100],
118
notEmpty: true
119
}
120
},
121
price: {
122
type: DataTypes.DECIMAL(10, 2),
123
allowNull: false,
124
validate: {
125
min: 0
126
}
127
},
128
description: {
129
type: DataTypes.TEXT,
130
allowNull: true
131
},
132
slug: {
133
type: DataTypes.VIRTUAL,
134
get() {
135
return this.name.toLowerCase().replace(/\s+/g, '-');
136
}
137
}
138
}, {
139
sequelize,
140
modelName: 'product',
141
tableName: 'products',
142
timestamps: true,
143
paranoid: true,
144
underscored: true,
145
indexes: [
146
{ fields: ['name'] },
147
{ fields: ['price'] }
148
]
149
});
150
```
151
152
### Model Schema Operations
153
154
Synchronize and manage model schemas in the database.
155
156
```typescript { .api }
157
/**
158
* Sync model with database
159
* @param options - Sync options
160
* @returns Promise resolving to the model class
161
*/
162
static sync(options?: SyncOptions): Promise<typeof Model>;
163
164
/**
165
* Drop model table from database
166
* @param options - Drop options
167
* @returns Promise resolving when table is dropped
168
*/
169
static drop(options?: DropOptions): Promise<void>;
170
171
/**
172
* Get table name for the model
173
* @returns Table name
174
*/
175
static getTableName(): string | { tableName: string; schema?: string; };
176
177
/**
178
* Describe table structure
179
* @returns Promise resolving to table description
180
*/
181
static describe(): Promise<ColumnsDescription>;
182
183
interface DropOptions {
184
/** Also drop dependent objects */
185
cascade?: boolean;
186
/** SQL query logging */
187
logging?: boolean | ((sql: string, timing?: number) => void);
188
}
189
```
190
191
**Usage Examples:**
192
193
```typescript
194
// Sync individual model
195
await User.sync();
196
197
// Force recreate table
198
await User.sync({ force: true });
199
200
// Drop table
201
await User.drop();
202
203
// Get table information
204
const tableName = User.getTableName();
205
const description = await User.describe();
206
```
207
208
### Model Validation
209
210
Define validation rules for model attributes and instances.
211
212
```typescript { .api }
213
interface ModelValidateOptions {
214
/** Built-in validators */
215
is?: string | RegExp;
216
not?: string | RegExp;
217
isEmail?: boolean;
218
isUrl?: boolean;
219
isIP?: boolean;
220
isAlpha?: boolean;
221
isAlphanumeric?: boolean;
222
isNumeric?: boolean;
223
isInt?: boolean;
224
isFloat?: boolean;
225
isDecimal?: boolean;
226
isLowercase?: boolean;
227
isUppercase?: boolean;
228
notNull?: boolean;
229
isNull?: boolean;
230
notEmpty?: boolean;
231
equals?: string;
232
contains?: string;
233
notIn?: any[][];
234
isIn?: any[][];
235
notContains?: string;
236
len?: [number, number];
237
isUUID?: number;
238
isDate?: boolean;
239
isAfter?: string;
240
isBefore?: string;
241
max?: number;
242
min?: number;
243
isCreditCard?: boolean;
244
245
/** Custom validator functions */
246
[key: string]: any;
247
}
248
249
/**
250
* Validate model instance
251
* @param options - Validation options
252
* @returns Promise that resolves if valid, rejects with ValidationError if invalid
253
*/
254
validate(options?: ValidationOptions): Promise<void>;
255
```
256
257
**Usage Examples:**
258
259
```typescript
260
class User extends Model {}
261
User.init({
262
email: {
263
type: DataTypes.STRING,
264
validate: {
265
isEmail: true,
266
notEmpty: true
267
}
268
},
269
age: {
270
type: DataTypes.INTEGER,
271
validate: {
272
min: 0,
273
max: 120,
274
isInt: true
275
}
276
},
277
username: {
278
type: DataTypes.STRING,
279
validate: {
280
len: [3, 20],
281
is: /^[a-zA-Z0-9_]+$/,
282
async isUnique(value) {
283
const user = await User.findOne({ where: { username: value } });
284
if (user) {
285
throw new Error('Username already exists');
286
}
287
}
288
}
289
}
290
}, {
291
sequelize,
292
modelName: 'user',
293
validate: {
294
// Model-level validation
295
emailOrPhone() {
296
if (!this.email && !this.phone) {
297
throw new Error('Either email or phone must be provided');
298
}
299
}
300
}
301
});
302
```
303
304
### Model Scopes
305
306
Define reusable query scopes for common filtering and inclusion patterns.
307
308
```typescript { .api }
309
interface ModelScopeOptions {
310
[scopeName: string]: FindOptions | (() => FindOptions);
311
}
312
313
/**
314
* Apply a scope to the model
315
* @param scopes - Scope names to apply
316
* @returns Scoped model class
317
*/
318
static scope(...scopes: (string | ScopeOptions)[]): typeof Model;
319
320
/**
321
* Remove all scopes from the model
322
* @returns Unscoped model class
323
*/
324
static unscoped(): typeof Model;
325
326
interface ScopeOptions {
327
method: [string, ...any[]];
328
}
329
```
330
331
**Usage Examples:**
332
333
```typescript
334
class User extends Model {}
335
User.init({
336
firstName: DataTypes.STRING,
337
lastName: DataTypes.STRING,
338
email: DataTypes.STRING,
339
isActive: DataTypes.BOOLEAN,
340
role: DataTypes.STRING
341
}, {
342
sequelize,
343
modelName: 'user',
344
scopes: {
345
// Static scope
346
active: {
347
where: { isActive: true }
348
},
349
// Dynamic scope with parameters
350
byRole: (role) => ({
351
where: { role }
352
}),
353
// Complex scope with includes
354
withOrders: {
355
include: [{ model: Order, as: 'orders' }]
356
}
357
},
358
defaultScope: {
359
where: { isActive: true }
360
}
361
});
362
363
// Using scopes
364
const activeUsers = await User.scope('active').findAll();
365
const admins = await User.scope({ method: ['byRole', 'admin'] }).findAll();
366
const usersWithOrders = await User.scope('active', 'withOrders').findAll();
367
const allUsers = await User.unscoped().findAll(); // Ignore default scope
368
```
369
370
### Instance Methods
371
372
Methods available on model instances for lifecycle management.
373
374
```typescript { .api }
375
/**
376
* Save instance to database
377
* @param options - Save options
378
* @returns Promise resolving to the saved instance
379
*/
380
save(options?: SaveOptions): Promise<this>;
381
382
/**
383
* Reload instance from database
384
* @param options - Reload options
385
* @returns Promise resolving to the reloaded instance
386
*/
387
reload(options?: FindOptions): Promise<this>;
388
389
/**
390
* Update instance attributes
391
* @param values - Values to update
392
* @param options - Update options
393
* @returns Promise resolving to the updated instance
394
*/
395
update(values: Partial<Attributes>, options?: InstanceUpdateOptions): Promise<this>;
396
397
/**
398
* Delete instance from database
399
* @param options - Destroy options
400
* @returns Promise resolving when instance is deleted
401
*/
402
destroy(options?: InstanceDestroyOptions): Promise<void>;
403
404
/**
405
* Restore soft-deleted instance
406
* @param options - Restore options
407
* @returns Promise resolving when instance is restored
408
*/
409
restore(options?: RestoreOptions): Promise<void>;
410
```
411
412
**Usage Examples:**
413
414
```typescript
415
// Create and modify instance
416
const user = User.build({ firstName: 'John', lastName: 'Doe' });
417
user.email = 'john@example.com';
418
await user.save();
419
420
// Update instance
421
await user.update({ firstName: 'Jane' });
422
423
// Reload from database
424
await user.reload();
425
426
// Soft delete (if paranoid: true)
427
await user.destroy();
428
429
// Restore soft-deleted
430
await user.restore();
431
```
432
433
### Attribute Access
434
435
Methods for getting and setting model attribute values.
436
437
```typescript { .api }
438
/**
439
* Get attribute value
440
* @param key - Attribute name
441
* @param options - Get options
442
* @returns Attribute value
443
*/
444
get(key?: string, options?: { plain?: boolean; clone?: boolean }): any;
445
446
/**
447
* Set attribute value
448
* @param key - Attribute name or object of key-value pairs
449
* @param value - Attribute value (if key is string)
450
* @param options - Set options
451
*/
452
set(key: string | object, value?: any, options?: { raw?: boolean; reset?: boolean }): void;
453
454
/**
455
* Get raw attribute value
456
* @param key - Attribute name
457
* @returns Raw attribute value
458
*/
459
getDataValue(key: string): any;
460
461
/**
462
* Set raw attribute value
463
* @param key - Attribute name
464
* @param value - Attribute value
465
*/
466
setDataValue(key: string, value: any): void;
467
468
/**
469
* Check if attribute has changed
470
* @param key - Attribute name
471
* @returns True if changed, false otherwise
472
*/
473
changed(key?: string): boolean | string[];
474
475
/**
476
* Get previous attribute value
477
* @param key - Attribute name
478
* @returns Previous value
479
*/
480
previous(key: string): any;
481
```
482
483
**Usage Example:**
484
485
```typescript
486
const user = await User.findByPk(1);
487
488
// Get values
489
const name = user.get('firstName');
490
const allValues = user.get({ plain: true });
491
492
// Set values
493
user.set('firstName', 'Jane');
494
user.set({ firstName: 'Jane', lastName: 'Smith' });
495
496
// Check for changes
497
if (user.changed()) {
498
console.log('Changed fields:', user.changed());
499
console.log('Previous name:', user.previous('firstName'));
500
}
501
502
// Raw data access
503
const rawValue = user.getDataValue('firstName');
504
user.setDataValue('firstName', 'John');
505
```
506
507
### Model Management
508
509
Static methods for managing model attributes and metadata.
510
511
```typescript { .api }
512
/**
513
* Get all model attributes
514
* @returns Object containing all attribute definitions
515
*/
516
static getAttributes(): ModelAttributes;
517
518
/**
519
* Remove an attribute from the model
520
* @param attribute - Attribute name to remove
521
*/
522
static removeAttribute(attribute: string): void;
523
524
/**
525
* Refresh model attributes from database
526
* @returns Promise resolving when attributes are refreshed
527
*/
528
static refreshAttributes(): Promise<void>;
529
530
/**
531
* Add a named scope to the model
532
* @param name - Scope name
533
* @param scope - Scope definition
534
* @param options - Scope options
535
*/
536
static addScope(name: string, scope: FindOptions | (() => FindOptions), options?: AddScopeOptions): void;
537
538
interface AddScopeOptions {
539
/** Override existing scope */
540
override?: boolean;
541
}
542
```
543
544
**Usage Examples:**
545
546
```typescript
547
// Get model attributes
548
const attributes = User.getAttributes();
549
console.log('User attributes:', Object.keys(attributes));
550
551
// Remove an attribute (e.g., after migration)
552
User.removeAttribute('deprecatedField');
553
554
// Refresh attributes after schema changes
555
await User.refreshAttributes();
556
557
// Add dynamic scopes
558
User.addScope('activeUsers', {
559
where: { isActive: true }
560
});
561
562
User.addScope('byRole', (role: string) => ({
563
where: { role }
564
}));
565
566
// Use added scopes
567
const activeUsers = await User.scope('activeUsers').findAll();
568
const admins = await User.scope({ method: ['byRole', 'admin'] }).findAll();
569
```