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
afterCreateandafterDeletehooks. - 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_READtransaction 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.maxto 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)
DECIMALandNEWDECIMALtypes now returned as String unlessjs dialectOptions: { decimalNumbers: true }is specified. - Removed support for referencesKey, use a references object
js references: { key: '', model: '' } -
classMethodsandinstanceMethodsare 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.Instanceandinstance.Modelare 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.Promiseinstead of global bluebirdPromise. - The CLS patch does not affect global bluebird promise. Transaction will not automatically get passed to methods when used with
Promise.alland other bluebird methods. Explicitly patch your bluebird instance to get CLS to work with bluebird methods.
$ npm install --save cls-bluebirdconst 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.Validatoris now an independent copy ofvalidatorlibraryDataTypes.DECIMALreturns string for MySQL and Postgres.DataTypes.DATEnow usesDATETIMEOFFSETinstead ofDATETIME2sql datatype in case of MSSQL to record timezone. To migrate existingDATETIME2columns intoDATETIMEOFFSET, see #7201.options.ordernow only accepts values with type of array or Sequelize method. Support for string values (ie{order: 'name DESC'}) has been deprecated.With
BelongsToManyrelationshipsadd/set/createsetters now set through attributes by passing them asoptions.through(previously second argument was used as through attributes, now it's considered options withthroughbeing a sub option)
Previous:
user.addProject(project, { status: 'started' })
New:
user.addProject(project, { through: { status: 'started' }})
-
DATEONLYnow returns string inYYYY-MM-DDformat rather thanDatetype -
Model.validateinstance 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.validateinstance 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.Utilsis not longer part of the public API, use it at your own risk -
Hooksshould return Promises now. Callbacks are deprecated. -
includeis always an array
Previous:
User.findAll({
include: {
model: Comment,
as: 'comments'
}
})
New:
User.findAll({
include: [{
model: Comment,
as: 'comments'
}]
})
-
whereclause insideincludedoes not make thisincludeand all its parentsrequired. You can use followingbeforeFindglobal 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 TABLEcommands 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
DEBUGsupport. You can now useDEBUG=sequelize* node app.jsto enable logging for all sequelize operations. To filter logged queries, useDEBUG=sequelize:sql:mssql sequelize:connection*to log generated SQL queries, connection info etc. -
JSONdatatype support has been added forSQLite -
UPSERTis now supported onMSSQLusingMERGEstatement. - Transactions are now fully supported on
MSSQL. - Filtered indexes are now supported on
MSSQLdialect.js queryInterface.addIndex( 'Person', ['firstname', 'lastname'], { where: { lastname: { $ne: null } } } )