Promise-based Node.js ORM tool for Postgres, MySQL, MariaDB, SQLite, Microsoft SQL Server, Amazon Redshift and Snowflake's Data Cloud with solid transaction support, relations, eager and lazy loading, read replication and more
—
Model creation, configuration, and lifecycle management including attributes, validations, scopes, and schema operations.
Initialize a model with attributes and configuration options.
/**
* Initialize model with attributes and options
* @param attributes - Model attribute definitions
* @param options - Model configuration options
* @returns The initialized model class
*/
static init(attributes: ModelAttributes, options: InitOptions): typeof Model;
interface ModelAttributes {
[name: string]: DataType | ModelAttributeColumnOptions;
}
interface ModelAttributeColumnOptions {
/** Column data type */
type: DataType;
/** Allow null values */
allowNull?: boolean;
/** Default value */
defaultValue?: any;
/** Primary key column */
primaryKey?: boolean;
/** Unique constraint */
unique?: boolean | string | { name: string; msg?: string };
/** Auto increment (integers only) */
autoIncrement?: boolean;
/** Column comment */
comment?: string;
/** Custom column name */
field?: string;
/** Validation rules */
validate?: ModelValidateOptions;
/** Virtual field getter */
get?: () => any;
/** Virtual field setter */
set?: (value: any) => void;
}
interface InitOptions {
/** Sequelize instance */
sequelize: Sequelize;
/** Model name */
modelName?: string;
/** Table name */
tableName?: string;
/** Schema name */
schema?: string;
/** Enable timestamps (createdAt, updatedAt) */
timestamps?: boolean;
/** Paranoid mode (soft delete) */
paranoid?: boolean;
/** Use underscored column names */
underscored?: boolean;
/** Freeze table name (disable pluralization) */
freezeTableName?: boolean;
/** Table indexes */
indexes?: IndexesOptions[];
/** Model hooks */
hooks?: Partial<ModelHooks>;
/** Model scopes */
scopes?: ModelScopeOptions;
/** Default scope */
defaultScope?: FindOptions;
/** Model validation options */
validate?: ModelValidateOptions;
}Usage Examples:
import { Model, DataTypes, Sequelize } from "sequelize";
const sequelize = new Sequelize("sqlite::memory:");
// Basic model definition
class User extends Model {}
User.init({
firstName: DataTypes.STRING,
lastName: DataTypes.STRING,
email: DataTypes.STRING
}, {
sequelize,
modelName: 'user'
});
// Advanced model with all options
class Product extends Model {
public id!: number;
public name!: string;
public price!: number;
public description?: string;
public createdAt!: Date;
public updatedAt!: Date;
}
Product.init({
id: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true
},
name: {
type: DataTypes.STRING(100),
allowNull: false,
unique: true,
validate: {
len: [3, 100],
notEmpty: true
}
},
price: {
type: DataTypes.DECIMAL(10, 2),
allowNull: false,
validate: {
min: 0
}
},
description: {
type: DataTypes.TEXT,
allowNull: true
},
slug: {
type: DataTypes.VIRTUAL,
get() {
return this.name.toLowerCase().replace(/\s+/g, '-');
}
}
}, {
sequelize,
modelName: 'product',
tableName: 'products',
timestamps: true,
paranoid: true,
underscored: true,
indexes: [
{ fields: ['name'] },
{ fields: ['price'] }
]
});Synchronize and manage model schemas in the database.
/**
* Sync model with database
* @param options - Sync options
* @returns Promise resolving to the model class
*/
static sync(options?: SyncOptions): Promise<typeof Model>;
/**
* Drop model table from database
* @param options - Drop options
* @returns Promise resolving when table is dropped
*/
static drop(options?: DropOptions): Promise<void>;
/**
* Get table name for the model
* @returns Table name
*/
static getTableName(): string | { tableName: string; schema?: string; };
/**
* Describe table structure
* @returns Promise resolving to table description
*/
static describe(): Promise<ColumnsDescription>;
interface DropOptions {
/** Also drop dependent objects */
cascade?: boolean;
/** SQL query logging */
logging?: boolean | ((sql: string, timing?: number) => void);
}Usage Examples:
// Sync individual model
await User.sync();
// Force recreate table
await User.sync({ force: true });
// Drop table
await User.drop();
// Get table information
const tableName = User.getTableName();
const description = await User.describe();Define validation rules for model attributes and instances.
interface ModelValidateOptions {
/** Built-in validators */
is?: string | RegExp;
not?: string | RegExp;
isEmail?: boolean;
isUrl?: boolean;
isIP?: boolean;
isAlpha?: boolean;
isAlphanumeric?: boolean;
isNumeric?: boolean;
isInt?: boolean;
isFloat?: boolean;
isDecimal?: boolean;
isLowercase?: boolean;
isUppercase?: boolean;
notNull?: boolean;
isNull?: boolean;
notEmpty?: boolean;
equals?: string;
contains?: string;
notIn?: any[][];
isIn?: any[][];
notContains?: string;
len?: [number, number];
isUUID?: number;
isDate?: boolean;
isAfter?: string;
isBefore?: string;
max?: number;
min?: number;
isCreditCard?: boolean;
/** Custom validator functions */
[key: string]: any;
}
/**
* Validate model instance
* @param options - Validation options
* @returns Promise that resolves if valid, rejects with ValidationError if invalid
*/
validate(options?: ValidationOptions): Promise<void>;Usage Examples:
class User extends Model {}
User.init({
email: {
type: DataTypes.STRING,
validate: {
isEmail: true,
notEmpty: true
}
},
age: {
type: DataTypes.INTEGER,
validate: {
min: 0,
max: 120,
isInt: true
}
},
username: {
type: DataTypes.STRING,
validate: {
len: [3, 20],
is: /^[a-zA-Z0-9_]+$/,
async isUnique(value) {
const user = await User.findOne({ where: { username: value } });
if (user) {
throw new Error('Username already exists');
}
}
}
}
}, {
sequelize,
modelName: 'user',
validate: {
// Model-level validation
emailOrPhone() {
if (!this.email && !this.phone) {
throw new Error('Either email or phone must be provided');
}
}
}
});Define reusable query scopes for common filtering and inclusion patterns.
interface ModelScopeOptions {
[scopeName: string]: FindOptions | (() => FindOptions);
}
/**
* Apply a scope to the model
* @param scopes - Scope names to apply
* @returns Scoped model class
*/
static scope(...scopes: (string | ScopeOptions)[]): typeof Model;
/**
* Remove all scopes from the model
* @returns Unscoped model class
*/
static unscoped(): typeof Model;
interface ScopeOptions {
method: [string, ...any[]];
}Usage Examples:
class User extends Model {}
User.init({
firstName: DataTypes.STRING,
lastName: DataTypes.STRING,
email: DataTypes.STRING,
isActive: DataTypes.BOOLEAN,
role: DataTypes.STRING
}, {
sequelize,
modelName: 'user',
scopes: {
// Static scope
active: {
where: { isActive: true }
},
// Dynamic scope with parameters
byRole: (role) => ({
where: { role }
}),
// Complex scope with includes
withOrders: {
include: [{ model: Order, as: 'orders' }]
}
},
defaultScope: {
where: { isActive: true }
}
});
// Using scopes
const activeUsers = await User.scope('active').findAll();
const admins = await User.scope({ method: ['byRole', 'admin'] }).findAll();
const usersWithOrders = await User.scope('active', 'withOrders').findAll();
const allUsers = await User.unscoped().findAll(); // Ignore default scopeMethods available on model instances for lifecycle management.
/**
* Save instance to database
* @param options - Save options
* @returns Promise resolving to the saved instance
*/
save(options?: SaveOptions): Promise<this>;
/**
* Reload instance from database
* @param options - Reload options
* @returns Promise resolving to the reloaded instance
*/
reload(options?: FindOptions): Promise<this>;
/**
* Update instance attributes
* @param values - Values to update
* @param options - Update options
* @returns Promise resolving to the updated instance
*/
update(values: Partial<Attributes>, options?: InstanceUpdateOptions): Promise<this>;
/**
* Delete instance from database
* @param options - Destroy options
* @returns Promise resolving when instance is deleted
*/
destroy(options?: InstanceDestroyOptions): Promise<void>;
/**
* Restore soft-deleted instance
* @param options - Restore options
* @returns Promise resolving when instance is restored
*/
restore(options?: RestoreOptions): Promise<void>;Usage Examples:
// Create and modify instance
const user = User.build({ firstName: 'John', lastName: 'Doe' });
user.email = 'john@example.com';
await user.save();
// Update instance
await user.update({ firstName: 'Jane' });
// Reload from database
await user.reload();
// Soft delete (if paranoid: true)
await user.destroy();
// Restore soft-deleted
await user.restore();Methods for getting and setting model attribute values.
/**
* Get attribute value
* @param key - Attribute name
* @param options - Get options
* @returns Attribute value
*/
get(key?: string, options?: { plain?: boolean; clone?: boolean }): any;
/**
* Set attribute value
* @param key - Attribute name or object of key-value pairs
* @param value - Attribute value (if key is string)
* @param options - Set options
*/
set(key: string | object, value?: any, options?: { raw?: boolean; reset?: boolean }): void;
/**
* Get raw attribute value
* @param key - Attribute name
* @returns Raw attribute value
*/
getDataValue(key: string): any;
/**
* Set raw attribute value
* @param key - Attribute name
* @param value - Attribute value
*/
setDataValue(key: string, value: any): void;
/**
* Check if attribute has changed
* @param key - Attribute name
* @returns True if changed, false otherwise
*/
changed(key?: string): boolean | string[];
/**
* Get previous attribute value
* @param key - Attribute name
* @returns Previous value
*/
previous(key: string): any;Usage Example:
const user = await User.findByPk(1);
// Get values
const name = user.get('firstName');
const allValues = user.get({ plain: true });
// Set values
user.set('firstName', 'Jane');
user.set({ firstName: 'Jane', lastName: 'Smith' });
// Check for changes
if (user.changed()) {
console.log('Changed fields:', user.changed());
console.log('Previous name:', user.previous('firstName'));
}
// Raw data access
const rawValue = user.getDataValue('firstName');
user.setDataValue('firstName', 'John');Static methods for managing model attributes and metadata.
/**
* Get all model attributes
* @returns Object containing all attribute definitions
*/
static getAttributes(): ModelAttributes;
/**
* Remove an attribute from the model
* @param attribute - Attribute name to remove
*/
static removeAttribute(attribute: string): void;
/**
* Refresh model attributes from database
* @returns Promise resolving when attributes are refreshed
*/
static refreshAttributes(): Promise<void>;
/**
* Add a named scope to the model
* @param name - Scope name
* @param scope - Scope definition
* @param options - Scope options
*/
static addScope(name: string, scope: FindOptions | (() => FindOptions), options?: AddScopeOptions): void;
interface AddScopeOptions {
/** Override existing scope */
override?: boolean;
}Usage Examples:
// Get model attributes
const attributes = User.getAttributes();
console.log('User attributes:', Object.keys(attributes));
// Remove an attribute (e.g., after migration)
User.removeAttribute('deprecatedField');
// Refresh attributes after schema changes
await User.refreshAttributes();
// Add dynamic scopes
User.addScope('activeUsers', {
where: { isActive: true }
});
User.addScope('byRole', (role: string) => ({
where: { role }
}));
// Use added scopes
const activeUsers = await User.scope('activeUsers').findAll();
const admins = await User.scope({ method: ['byRole', 'admin'] }).findAll();Install with Tessl CLI
npx tessl i tessl/npm-sequelize