Upgrade to V4
Sequelize V4 is a major release and it introduces new features and breaking changes. Majority of sequelize codebase has been refactored to use ES2015 features. The following guide lists some of the changes to upgrade from v3 to v4. See the Changelog for full list of changes.
Breaking Changes
- Node version: To use new ES2015 features, we now require at least Node 4. From now on, we will support all current LTS versions of Node.
- The counter cache plugin, and consequently the counterCache option for associations has been removed. The same behaviour can be achieved using
afterCreate
andafterDelete
hooks. - Removed MariaDB dialect. This was just a thin wrapper around MySQL, so using
dialect: 'mysql'
instead should work with no further changes - Removed default
REPEATABLE_READ
transaction isolation. The isolation level now defaults to that of the database. Explicitly pass the required isolation level when initiating the transaction. - Removed support for
pool: false
. To use a single connection, setpool.max
to 1. - Removed support for old connection pooling configuration keys. Instead of
js pool: { maxIdleTime: 30000, minConnections: 20, maxConnections: 30 }
use
pool: {
idle: 30000,
min: 20,
max: 30
}
- (MySQL) BIGINT now gets converted to string when number is too big
- (MySQL)
DECIMAL
andNEWDECIMAL
types now returned as String unlessjs dialectOptions: { decimalNumbers: true }
is specified. - Removed support for referencesKey, use a references object
js references: { key: '', model: '' }
-
classMethods
andinstanceMethods
are removed.
Previous:
const Model = sequelize.define('Model', {
...
}, {
classMethods: {
associate: function (model) {...}
},
instanceMethods: {
someMethod: function () { ...}
}
});
New:
const Model = sequelize.define('Model', {
...
});
// Class Method
Model.associate = function (models) {
...associate the models
};
// Instance Method
Model.prototype.someMethod = function () {..}
-
Model.Instance
andinstance.Model
are removed. To access the Model from an instance, simply useinstance.constructor
. The Instance class (Model.Instance
) is now the Model itself. -
Sequelize now uses an independent copy of bluebird library.
- Promises returned by sequelize are now instances of
Sequelize.Promise
instead of global bluebirdPromise
. - The CLS patch does not affect global bluebird promise. Transaction will not automatically get passed to methods when used with
Promise.all
and other bluebird methods. Explicitly patch your bluebird instance to get CLS to work with bluebird methods.
$ npm install --save cls-bluebird
const Promise = require('bluebird'); const Sequelize = require('sequelize'); const cls = require('continuation-local-storage'); const ns = cls.createNamespace('transaction-namespace'); const clsBluebird = require('cls-bluebird'); clsBluebird(ns, Promise); Sequelize.useCLS(ns);
- Promises returned by sequelize are now instances of
Sequelize.Validator
is now an independent copy ofvalidator
libraryDataTypes.DECIMAL
returns string for MySQL and Postgres.DataTypes.DATE
now usesDATETIMEOFFSET
instead ofDATETIME2
sql datatype in case of MSSQL to record timezone. To migrate existingDATETIME2
columns intoDATETIMEOFFSET
, see #7201.options.order
now only accepts values with type of array or Sequelize method. Support for string values (ie{order: 'name DESC'}
) has been deprecated.With
BelongsToMany
relationshipsadd/set/create
setters now set through attributes by passing them asoptions.through
(previously second argument was used as through attributes, now it's considered options withthrough
being a sub option)
Previous:
user.addProject(project, { status: 'started' })
New:
user.addProject(project, { through: { status: 'started' }})
-
DATEONLY
now returns string inYYYY-MM-DD
format rather thanDate
type -
Model.validate
instance method now runs validation hooks by default. Previously you needed to pass{ hooks: true }
. You can override this behavior by passing{ hooks: false }
- The resulting promise from the
Model.validate
instance method will be rejected when validation fails. It will fulfill when validation succeeds. - Raw options for where, order and group like
where: { $raw: '..', order: [{ raw: '..' }], group: [{ raw: '..' }] }
have been removed to prevent SQL injection attacks. -
Sequelize.Utils
is not longer part of the public API, use it at your own risk -
Hooks
should return Promises now. Callbacks are deprecated. -
include
is always an array
Previous:
User.findAll({
include: {
model: Comment,
as: 'comments'
}
})
New:
User.findAll({
include: [{
model: Comment,
as: 'comments'
}]
})
-
where
clause insideinclude
does not make thisinclude
and all its parentsrequired
. You can use followingbeforeFind
global hook to keep previous behaviour:
function whereRequiredLikeInV3(modelDescriptor) {
if (!modelDescriptor.include) {
return false;
}
return modelDescriptor.include.some(relatedModelDescriptor => {
const childDescriptorRequired = whereRequiredLikeInV3(
relatedModelDescriptor,
);
if (
(relatedModelDescriptor.where || childDescriptorRequired) &&
typeof relatedModelDescriptor.required === 'undefined'
) {
relatedModelDescriptor.required = true;
}
return relatedModelDescriptor.required;
});
}
const sequelize = new Sequelize(..., {
...,
define: {
hooks: {
beforeFind: whereRequiredLikeInV3,
},
},
});
New features
- Initial version of
sequelize.sync({ alter: true })
has been added and usesALTER TABLE
commands to sync tables. Migrations are still preferred and should be used in production. - Adding and removing database contraints are now supported. Existing primary, foreignKey and other contraints can now be added/removed using migrations - See more.
- Instances (database rows) are now instances of the model, instead of being an instance of a separate class. This means you can replace
User.build()
withnew User()
andsequelize.define(attributes, options)
withjs class User extends Sequelize.Model {} User.init(attributes, options)
You can then define custom methods, class methods and getters/setter directly in the class. This also enables more usage patterns, for example with decorators. - Added
DEBUG
support. You can now useDEBUG=sequelize* node app.js
to enable logging for all sequelize operations. To filter logged queries, useDEBUG=sequelize:sql:mssql sequelize:connection*
to log generated SQL queries, connection info etc. -
JSON
datatype support has been added forSQLite
-
UPSERT
is now supported onMSSQL
usingMERGE
statement. - Transactions are now fully supported on
MSSQL
. - Filtered indexes are now supported on
MSSQL
dialect.js queryInterface.addIndex( 'Person', ['firstname', 'lastname'], { where: { lastname: { $ne: null } } } )