不要怂,就是干,撸起袖子干!

Commit b75a6c29 by Jan Aagaard Meier

Moved docs to main repo

1 parent 78cf2b4a
......@@ -9,5 +9,3 @@ test/binary/tmp/*
test/tmp/*
test/sqlite/test.sqlite
coverage-*
docs/*.md
docs/*.html
\ No newline at end of file
# Documentation
The sequelize documentation is written in a combination of markdown (articles and example based documentation) and [JSDoc](http://usejsdoc.org) (API reference generated from source code comments).
All documentation is located in `docs` folder.
The documentation is rendered using [mkdocs](http://mkdocs.org) and hosted at [Read the docs](http://sequelize.readthedocs.org). Mkdocs generates static HTML from markdown files. The files in `articles` and `docs` should be edited directly, and the files in `api` are generated from source code comments (more on that later).
All pages in the documentation are defined in `mkdocs.yml`, in the `pages` section. Each page is given as a separate line:
```yml
- ['index.md', 'Home', 'Welcome']
```
The first array element is the path of the markdown file, relative to the `docs` dir. The second element is the section the page should be placed in, and the third is the name of the page.
To view the docs locally use `mkdocs serve`. This will start a local server at port 8000. The documentation is automatically regenerated when you edit an `.md` file. However, you'll have to restart the server if you add new pages in the configuration file.
## Articles and example based docs
Write markdown, and have fun :)
## API docs
The API documentation is generated from source code comments by a custom script, which outputs markdown into the `docs/api` folder. To regenerate the documentation, run
```bash
$ npm run docs
```
By default all generation will be regenerated, but you can run the generation for a single file by specifying `--file`.
......@@ -90,9 +90,3 @@ coveralls: sqlite-cover mysql-cover postgres-cover postgres-native-cover mariadb
codeclimate: sqlite-cover mysql-cover postgres-cover postgres-native-cover mariadb-cover merge-coverage codeclimate-send
.PHONY: sqlite mysql postgres pgsql postgres-native postgresn all test
api-docs:
node docs/docs-generator.js
clean:
node docs/docs-generator.js --clean
<a name="mixin"></a>
# Mixin Mixin
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/associations/mixin.js#L94)
Creating assocations in sequelize is done by calling one of the belongsTo / hasOne / hasMany functions
on a model (the source), and prodiving another model as the first argument to the function (the target).
* hasOne - adds a foreign key to target
* belongsTo - add a foreign key to source
* hasMany - adds a foreign key to target, unless you also specifiy that target hasMany source, in which case a junction table is created with sourceId and targetId
Creating an association will add a foreign key constraint to the attributes. All associations use `CASCADE` on update and `SET NULL` on delete, except for n:m, which also uses `CASCADE` on delete.
When creating associations, you can provide an alias, via the `as` option. This is usefull if the same model
is associated twice, or you want your association to be called something other than the name of the target model.
As an example, consider the case where users have many pictures, one of which is their profile picture. All pictures
have a `userId`, but in addition the user model also has a `profilePictureId`, to be able to easily load the user's profile
picture.
```js
User.hasMany(Picture)
User.belongsTo(Picture, { as: 'ProfilePicture', constraints: false })
user.getPictures() // gets you all pictures
user.getProfilePicture() // gets you only the profile picture
User.findAll({
where: ...,
include: [
{ model: Picture }, // load all pictures
{ model: Picture, as: 'ProfilePicture' }, // load the profile picture. Notice that the spelling must be the exact same as the one in the association
]
})
```
To get full control over the foreign key column added by sequelize, you can use the `foreignKey` option. It can either be a string, that specifies the name, or and object type definition,
equivalent to those passed to `sequelize.define`.
```js
User.hasMany(Picture, { foreignKey: 'uid' })
```
The foreign key column in Picture will now be called `uid` instead of the default `userId`.
```js
User.hasMany(Picture, {
foreignKey: {
name: 'uid'
allowNull: false
}
})
```
This specifies that the `uid` column can not be null. In most cases this will already be covered by the foreign key costraints, which sequelize creates automatically,
but can be usefull in case where the foreign keys are disabled, e.g. due to circular references (see `constraints: false` below).
When fetching associated models, you can limit your query to only load some models. These queries are written in the same way as queries to `find`/`findAll`. To only get pictures in JPG, you can do:
```js
user.getPictures({
where: {
format: 'jpg'
}
})
```
There are several ways to update and add new assoications. Continuing with our example of users and pictures:
```js
user.addPicture(p) // Add a single picture
user.setPictures([p1, p2]) // Associate user with ONLY these two picture, all other associations will be deleted
user.addPictures([p1, p2]) // Associate user with these two pictures, but don't touch any current associations
```
You don't have to pass in a complete object to the association functions, if your associated model has a single primary key:
```js
user.addPicture(req.query.pid) // Here pid is just an integer, representing the primary key of the picture
```
In the example above we have specified that a user belongs to his profile picture. Conceptually, this might not make sense,
but since we want to add the foreign key to the user model this is the way to do it.
Note how we also specified `constraints: false` for profile picture. This is because we add a foreign key from
user to picture (profilePictureId), and from picture to user (userId). If we were to add foreign keys to both, it would
create a cyclic dependency, and sequelize would not know which table to create first, since user depends on picture, and picture
depends on user. These kinds of problems are detected by sequelize before the models are synced to the database, and you will
get an error along the lines of `Error: Cyclic dependency found. 'users' is dependent of itself`. If you encounter this,
you should either disable some constraints, or rethink your associations completely.
***
<a name="hasone"></a>
## `hasOne(target, [options])`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/associations/mixin.js#L144)
Creates an association between this (the source) and the provided target. The foreign key is added on the target.
Example: `User.hasOne(Profile)`. This will add userId to the profile table.
The following methods are injected on the source:
* get[AS] - for example getProfile(finder). The finder object is passed to `target.find`.
* set[AS] - for example setProfile(instance, options). Options are passed to `target.save`
* create[AS] - for example createProfile(value, options). Builds and saves a new instance of the associated model. Values and options are passed on to `target.create`
All methods return a promise
**Params:**
| Name | Type | Description |
| ---- | ---- | ----------- |
| target | Model | |
| [options] | object | |
| [options.hooks=false] | boolean | Set to true to run before-/afterDestroy hooks when an associated model is deleted because of a cascade. For example if `User.hasOne(Profile, {onDelete: 'cascade', hooks:true})`, the before-/afterDestroy hooks for profile will be called when a user is deleted. Otherwise the profile will be deleted without invoking any hooks |
| [options.as] | string | The alias of this model, in singular form. See also the `name` option passed to `sequelize.define`. If you create multiple associations between the same tables, you should provide an alias to be able to distinguish between them. If you provide an alias when creating the assocition, you should provide the same alias when eager loading and when getting assocated models. Defaults to the singularized name of target |
| [options.foreignKey] | string &#124; object | The name of the foreign key in the target table or an object representing the type definition for the foreign column (see `Sequelize.define` for syntax). When using an object, you can add a `name` property to set the name of the colum. Defaults to the name of source + primary key of source |
| [options.onDelete='SET&nbsp;NULL'] | string | |
| [options.onUpdate='CASCADE'] | string | |
| [options.constraints=true] | boolean | Should on update and on delete constraints be enabled on the foreign key. |
***
<a name="belongsto"></a>
## `belongsTo(target, [options])`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/associations/mixin.js#L169)
Creates an association between this (the source) and the provided target. The foreign key is added on the source.
Example: `Profile.belongsTo(User)`. This will add userId to the profile table.
The following methods are injected on the source:
* get[AS] - for example getUser(finder). The finder object is passed to `target.find`.
* set[AS] - for example setUser(instance, options). Options are passed to this.save
* create[AS] - for example createUser(value, options). Builds and saves a new instance of the associated model. Values and options are passed on to target.create
All methods return a promise
**Params:**
| Name | Type | Description |
| ---- | ---- | ----------- |
| target | Model | |
| [options] | object | |
| [options.hooks=false] | boolean | Set to true to run before-/afterDestroy hooks when an associated model is deleted because of a cascade. For example if `User.hasOne(Profile, {onDelete: 'cascade', hooks:true})`, the before-/afterDestroy hooks for profile will be called when a user is deleted. Otherwise the profile will be deleted without invoking any hooks |
| [options.as] | string | The alias of this model, in singular form. See also the `name` option passed to `sequelize.define`. If you create multiple associations between the same tables, you should provide an alias to be able to distinguish between them. If you provide an alias when creating the assocition, you should provide the same alias when eager loading and when getting assocated models. Defaults to the singularized name of target |
| [options.foreignKey] | string &#124; object | The name of the foreign key in the source table or an object representing the type definition for the foreign column (see `Sequelize.define` for syntax). When using an object, you can add a `name` property to set the name of the colum. Defaults to the name of target + primary key of target |
| [options.onDelete='SET&nbsp;NULL'] | string | |
| [options.onUpdate='CASCADE'] | string | |
| [options.constraints=true] | boolean | Should on update and on delete constraints be enabled on the foreign key. |
***
<a name="hasmany"></a>
## `hasMany(target, [options])`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/associations/mixin.js#L244)
Create an association that is either 1:m or n:m.
```js
// Create a 1:m association between user and project
User.hasMany(Project)
```
```js
// Create a n:m association between user and project
User.hasMany(Project)
Project.hasMany(User)
```
By default, the name of the join table will be source+target, so in this case projectsusers. This can be overridden by providing either a string or a Model as `through` in the options.
The following methods are injected on the source:
* get[AS] - for example getPictures(finder). The finder object is passed to `target.find`.
* set[AS] - for example setPictures(instances, defaultAttributes|options). Update the associations. All currently associated models that are not in instances will be removed.
* add[AS] - for example addPicture(instance, defaultAttributes|options). Add another associated object.
* add[AS] [plural] - for example addPictures([instance1, instance2], defaultAttributes|options). Add some more associated objects.
* create[AS] - for example createPicture(values, options). Build and save a new association.
* remove[AS] - for example removePicture(instance). Remove a single association.
* remove[AS] [plural] - for example removePictures(instance). Remove multiple association.
* has[AS] - for example hasPicture(instance). Is source associated to this target?
* has[AS] [plural] - for example hasPictures(instances). Is source associated to all these targets?
All methods return a promise
If you use a through model with custom attributes, these attributes can be set when adding / setting new associations in two ways. Consider users and projects from before
with a join table that stores whether the project has been started yet:
```js
var UserProjects = sequelize.define('userprojects', {
started: Sequelize.BOOLEAN
})
User.hasMany(Project, { through: UserProjects })
Project.hasMany(User, { through: UserProjects })
```
```js
jan.addProject(homework, { started: false }) // The homework project is not started yet
jan.setProjects([makedinner, doshopping], { started: true}) // Both shopping and dinner has been started
```
If you want to set several target instances, but with different attributes you have to set the attributes on the instance, using a property with the name of the through model:
```js
p1.userprojects {
started: true
}
user.setProjects([p1, p2], {started: false}) // The default value is false, but p1 overrides that.
```
Similarily, when fetching through a join table with custom attributes, these attributes will be available as an object with the name of the through model.
```js
user.getProjects().success(function (projects) {
var p1 = projects[0]
p1.userprojects.started // Is this project started yet?
})
```
**Params:**
| Name | Type | Description |
| ---- | ---- | ----------- |
| target | Model | |
| [options] | object | |
| [options.hooks=false] | boolean | Set to true to run before-/afterDestroy hooks when an associated model is deleted because of a cascade. For example if `User.hasOne(Profile, {onDelete: 'cascade', hooks:true})`, the before-/afterDestroy hooks for profile will be called when a user is deleted. Otherwise the profile will be deleted without invoking any hooks |
| [options.through] | Model &#124; string|object | The name of the table that is used to join source and target in n:m associations. Can also be a sequelize model if you want to define the junction table yourself and add extra attributes to it. |
| [options.through.model] | Model | The model used to join both sides of the N:M association. |
| [options.through.scope] | object | A key/value set that will be used for association create and find defaults on the through model. (Remember to add the attributes to the through model) |
| [options.through.unique=true] | boolean | If true a unique key will be generated from the foreign keys used (might want to turn this off and create specific unique keys when using scopes) |
| [options.as] | string &#124; object | The alias of this model. If you provide a string, it should be plural, and will be singularized using node.inflection. If you want to control the singular version yourself, provide an object with `plural` and `singular` keys. See also the `name` option passed to `sequelize.define`. If you create multiple associations between the same tables, you should provide an alias to be able to distinguish between them. If you provide an alias when creating the assocition, you should provide the same alias when eager loading and when getting assocated models. Defaults to the pluralized name of target |
| [options.foreignKey] | string &#124; object | The name of the foreign key in the target table / join table or an object representing the type definition for the foreign column (see `Sequelize.define` for syntax). When using an object, you can add a `name` property to set the name of the colum. Defaults to the name of source + primary key of source |
| [options.scope] | object | A key/value set that will be used for association create and find defaults on the target. (sqlite not supported for N:M) |
| [options.onDelete='SET&nbsp;NULL|CASCADE'] | string | Cascade if this is a n:m, and set null if it is a 1:m |
| [options.onUpdate='CASCADE'] | string | |
| [options.constraints=true] | boolean | Should on update and on delete constraints be enabled on the foreign key. |
***
_This document is automatically generated based on source code comments. Please do not edit it directly, as your changes will be ignored. Please write on <a href="irc://irc.freenode.net/#sequelizejs">IRC</a>, open an issue or a create a pull request if you feel something can be improved. For help on how to write source code documentation see [JSDoc](http://usejsdoc.org) and [dox](https://github.com/tj/dox)_
\ No newline at end of file
<a name="datatypes"></a>
# Class DataTypes
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/data-types.js#L309)
A convenience class holding commonly used data types. The datatypes are used when definining a new model using `Sequelize.define`, like this:
```js
sequelize.define('model', {
column: DataTypes.INTEGER
})
```
When defining a model you can just as easily pass a string as type, but often using the types defined here is beneficial. For example, using `DataTypes.BLOB`, mean
that that column will be returned as an instance of `Buffer` when being fetched by sequelize.
Some data types have special properties that can be accessed in order to change the data type. For example, to get an unsigned integer with zerofill you can do `DataTypes.INTEGER.UNSIGNED.ZEROFILL`.
The order you access the properties in do not matter, so `DataTypes.INTEGER.ZEROFILL.UNSIGNED` is fine as well. The available properties are listed under each data type.
To provide a length for the data type, you can invoke it like a function: `INTEGER(2)`
Three of the values provided here (`NOW`, `UUIDV1` and `UUIDV4`) are special default values, that should not be used to define types. Instead they are used as shorthands for
defining default values. For example, to get a uuid field with a default value generated following v1 of the UUID standard:
```js
sequelize.define('model', {
uuid: {
type: DataTypes.UUID,
defaultValue: DataTypes.UUIDV1,
primaryKey: true
}
})
```
***
<a name="string"></a>
## `STRING`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/data-types.js#L317)
A variable length string. Default length 255
Available properties: `BINARY`
***
<a name="char"></a>
## `CHAR`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/data-types.js#L325)
A fixed length string. Default length 255
Available properties: `BINARY`
***
<a name="text"></a>
## `TEXT`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/data-types.js#L330)
An unlimited length text column
***
<a name="integer"></a>
## `INTEGER`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/data-types.js#L338)
A 32 bit integer.
Available properties: `UNSIGNED`, `ZEROFILL`
***
<a name="bigint"></a>
## `BIGINT`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/data-types.js#L346)
A 64 bit integer.
Available properties: `UNSIGNED`, `ZEROFILL`
***
<a name="date"></a>
## `DATE`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/data-types.js#L351)
A datetime column
***
<a name="dateonly"></a>
## `DATEONLY`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/data-types.js#L356)
A date only column
***
<a name="boolean"></a>
## `BOOLEAN`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/data-types.js#L361)
A boolean / tinyint column, depending on dialect
***
<a name="float"></a>
## `FLOAT`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/data-types.js#L369)
Floating point number. Accepts one or two arguments for precision
Available properties: `UNSIGNED`, `ZEROFILL`
***
<a name="now"></a>
## `NOW`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/data-types.js#L374)
A default value of the current timestamp
***
<a name="blob"></a>
## `BLOB`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/data-types.js#L380)
Binary storage. Available lengths: `tiny`, `medium`, `long`
***
<a name="decimal"></a>
## `DECIMAL`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/data-types.js#L388)
Decimal number. Accepts one or two arguments for precision
Available properties: `UNSIGNED`, `ZEROFILL`
***
<a name="uuid"></a>
## `UUID`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/data-types.js#L393)
A column storing a unique univeral identifier. Use with `UUIDV1` or `UUIDV4` for default values.
***
<a name="uuidv1"></a>
## `UUIDV1`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/data-types.js#L398)
A default unique universal identifier generated following the UUID v1 standard
***
<a name="uuidv4"></a>
## `UUIDV4`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/data-types.js#L403)
A default unique universal identifier generated following the UUID v2 standard
***
<a name="hstore"></a>
## `HSTORE`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/data-types.js#L409)
A key / value column. Only available in postgres.
***
<a name="virtual"></a>
## `VIRTUAL`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/data-types.js#L449)
A virtual value that is not stored in the DB. This could for example be useful if you want to provide a default value in your model
that is returned to the user but not stored in the DB.
You could also use it to validate a value before permuting and storing it. Checking password length before hashing it for example:
```js
sequelize.define('user', {
password_hash: DataTypes.STRING
password: {
type: DataTypes.VIRTUAL,
set: function (val) {
this.setDataValue('password', val);
this.setDataValue('password_hash', this.salt + val);
},
validate: {
isLongEnough: function (val) {
if (val.length < 7) {
throw new Error("Please choose a longer password")
}
}
}
}
})
```
In the above code the password is stored plainly in the password field so it can be validated, but is never stored in the DB.
__Aliases:__ NONE
***
<a name="enum"></a>
## `ENUM`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/data-types.js#L457)
An enumeration. `DataTypes.ENUM('value', 'another value')`.
***
<a name="array"></a>
## `ARRAY()`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/data-types.js#L477)
An array of `type`, e.g. `DataTypes.ARRAY(DataTypes.DECIMAL)`. Only available in postgres.
***
_This document is automatically generated based on source code comments. Please do not edit it directly, as your changes will be ignored. Please write on <a href="irc://irc.freenode.net/#sequelizejs">IRC</a>, open an issue or a create a pull request if you feel something can be improved. For help on how to write source code documentation see [JSDoc](http://usejsdoc.org) and [dox](https://github.com/tj/dox)_
\ No newline at end of file
<a name="errors"></a>
# Class Errors
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/errors.js#L11)
Sequelize provides a host of custom error classes, to allow you to do easier debugging. All of these errors are exposed on the sequelize object and the sequelize constructor.
All sequelize errors inherit from the base JS error object.
***
<a name="baseerror"></a>
## `new BaseError()`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/errors.js#L20)
The Base Error all Sequelize Errors inherit from.
__Aliases:__ Error
***
<a name="validationerror"></a>
## `new ValidationError(message, [errors])`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/errors.js#L40)
Validation Error. Thrown when the sequelize validation has failed. The error contains an `errors` property,
which is an array with 1 or more ValidationErrorItems, one for each validation that failed.
**Params:**
| Name | Type | Description |
| ---- | ---- | ----------- |
| message | string | Error message |
| [errors] | Array | Array of ValidationErrorItem objects describing the validation errors |
__Extends:__ BaseError
***
<a name="get"></a>
## `get(path)`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/errors.js#L53)
Gets all validation error items for the path / field specified.
**Params:**
| Name | Type | Description |
| ---- | ---- | ----------- |
| path | string | The path to be checked for error items |
***
<a name="errors"></a>
## `errors()`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/errors.js#L67)
An array of ValidationErrorItems
***
<a name="databaseerror"></a>
## `new DatabaseError()`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/errors.js#L74)
A base class for all database related errors.
__Extends:__ BaseError
***
<a name="parent"></a>
## `parent()`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/errors.js#L88)
The database specific error which triggered this one
***
<a name="sql"></a>
## `sql()`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/errors.js#L94)
The SQL that triggered the error
***
<a name="timeouterror"></a>
## `new TimeoutError()`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/errors.js#L101)
Thrown when a database query times out because of a deadlock
__Extends:__ DatabaseError
***
<a name="uniqueconstrainterror"></a>
## `new UniqueConstraintError()`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/errors.js#L112)
Thrown when a unique constraint is violated in the database
__Extends:__ DatabaseError
***
<a name="foreignkeyconstrainterror"></a>
## `new ForeignKeyConstraintError()`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/errors.js#L131)
Thrown when a foreign key constraint is violated in the database
__Extends:__ DatabaseError
***
<a name="message"></a>
## `message()`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/errors.js#L151)
The message from the DB.
***
<a name="fields"></a>
## `fields()`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/errors.js#L157)
The fields of the unique constraint
***
<a name="value"></a>
## `value()`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/errors.js#L163)
The value(s) which triggered the error
***
<a name="index"></a>
## `index()`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/errors.js#L169)
The name of the index that triggered the error
***
<a name="validationerroritem"></a>
## `new ValidationErrorItem(message, type, path, value)`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/errors.js#L181)
Validation Error Item
Instances of this class are included in the `ValidationError.errors` property.
**Params:**
| Name | Type | Description |
| ---- | ---- | ----------- |
| message | string | An error message |
| type | string | The type of the validation error |
| path | string | The field that triggered the validation error |
| value | string | The value that generated the error |
***
_This document is automatically generated based on source code comments. Please do not edit it directly, as your changes will be ignored. Please write on <a href="irc://irc.freenode.net/#sequelizejs">IRC</a>, open an issue or a create a pull request if you feel something can be improved. For help on how to write source code documentation see [JSDoc](http://usejsdoc.org) and [dox](https://github.com/tj/dox)_
\ No newline at end of file
<a name="hooks"></a>
# Mixin Hooks
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/hooks.js#L37)
Hooks are function that are called before and after (bulk-) creation/updating/deletion and validation. Hooks can be added to you models in three ways:
1. By specifying them as options in `sequelize.define`
2. By calling `hook()` with a string and your hook handler function
3. By calling the function with the same name as the hook you want
```js
// Method 1
sequelize.define(name, { attributes }, {
hooks: {
beforeBulkCreate: function () {
// can be a single function
},
beforeValidate: [
function () {},
function() {} // Or an array of several
]
}
})
// Method 2
Model.hook('afterDestroy', function () {})
// Method 3
Model.afterBulkUpdate(function () {})
```
**See:**
* [Sequelize#define](sequelize#define)
***
<a name="addhook"></a>
## `addHook(hooktype, [name], fn)`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/hooks.js#L149)
Add a hook to the model
**Params:**
| Name | Type | Description |
| ---- | ---- | ----------- |
| hooktype | String | |
| [name] | String | Provide a name for the hook function. This serves no purpose, other than the ability to be able to order hooks based on some sort of priority system in the future. |
| fn | Function | The hook function |
__Aliases:__ hook
***
<a name="beforevalidate"></a>
## `beforeValidate(name, fn)`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/hooks.js#L169)
A hook that is run before validation
**Params:**
| Name | Type | Description |
| ---- | ---- | ----------- |
| name | String | |
| fn | Function | A callback function that is called with instance, options, callback(err) |
***
<a name="aftervalidate"></a>
## `afterValidate(name, fn)`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/hooks.js#L178)
A hook that is run after validation
**Params:**
| Name | Type | Description |
| ---- | ---- | ----------- |
| name | String | |
| fn | Function | A callback function that is called with instance, options, callback(err) |
***
<a name="beforecreate"></a>
## `beforeCreate(name, fn)`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/hooks.js#L187)
A hook that is run before creating a single instance
**Params:**
| Name | Type | Description |
| ---- | ---- | ----------- |
| name | String | |
| fn | Function | A callback function that is called with attributes, options, callback(err) |
***
<a name="aftercreate"></a>
## `afterCreate(name, fn)`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/hooks.js#L196)
A hook that is run after creating a single instance
**Params:**
| Name | Type | Description |
| ---- | ---- | ----------- |
| name | String | |
| fn | Function | A callback function that is called with attributes, options, callback(err) |
***
<a name="beforedestroy"></a>
## `beforeDestroy(name, fn)`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/hooks.js#L207)
A hook that is run before destroying a single instance
**Params:**
| Name | Type | Description |
| ---- | ---- | ----------- |
| name | String | |
| fn | Function | A callback function that is called with instance, options, callback(err) |
__Aliases:__ beforeDelete
***
<a name="afterdestroy"></a>
## `afterDestroy(name, fn)`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/hooks.js#L222)
A hook that is run after destroying a single instance
**Params:**
| Name | Type | Description |
| ---- | ---- | ----------- |
| name | String | |
| fn | Function | A callback function that is called with instance, options, callback(err) |
__Aliases:__ afterDelete
***
<a name="beforeupdate"></a>
## `beforeUpdate(name, fn)`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/hooks.js#L235)
A hook that is run before updating a single instance
**Params:**
| Name | Type | Description |
| ---- | ---- | ----------- |
| name | String | |
| fn | Function | A callback function that is called with instance, options, callback(err) |
***
<a name="afterupdate"></a>
## `afterUpdate(name, fn)`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/hooks.js#L244)
A hook that is run after updating a single instance
**Params:**
| Name | Type | Description |
| ---- | ---- | ----------- |
| name | String | |
| fn | Function | A callback function that is called with instance, options, callback(err) |
***
<a name="beforebulkcreate"></a>
## `beforeBulkCreate(name, fn)`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/hooks.js#L253)
A hook that is run before creating instances in bulk
**Params:**
| Name | Type | Description |
| ---- | ---- | ----------- |
| name | String | |
| fn | Function | A callback function that is called with instances, options, callback(err) |
***
<a name="afterbulkcreate"></a>
## `afterBulkCreate(name, fn)`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/hooks.js#L262)
A hook that is run after creating instances in bulk
**Params:**
| Name | Type | Description |
| ---- | ---- | ----------- |
| name | String | |
| fn | Function | A callback function that is called with instances, options, callback(err) |
***
<a name="beforebulkdestroy"></a>
## `beforeBulkDestroy(name, fn)`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/hooks.js#L273)
A hook that is run before destroying instances in bulk
**Params:**
| Name | Type | Description |
| ---- | ---- | ----------- |
| name | String | |
| fn | Function | A callback function that is called with options, callback(err) |
__Aliases:__ beforeBulkDelete
***
<a name="afterbulkdestroy"></a>
## `afterBulkDestroy(name, fn)`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/hooks.js#L288)
A hook that is run after destroying instances in bulk
**Params:**
| Name | Type | Description |
| ---- | ---- | ----------- |
| name | String | |
| fn | Function | A callback function that is called with options, callback(err) |
__Aliases:__ afterBulkDelete
***
<a name="beforebulkupdate"></a>
## `beforeBulkUpdate(name, fn)`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/hooks.js#L301)
A hook that is run after updating instances in bulk
**Params:**
| Name | Type | Description |
| ---- | ---- | ----------- |
| name | String | |
| fn | Function | A callback function that is called with options, callback(err) |
***
<a name="afterbulkupdate"></a>
## `afterBulkUpdate(name, fn)`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/hooks.js#L310)
A hook that is run after updating instances in bulk
**Params:**
| Name | Type | Description |
| ---- | ---- | ----------- |
| name | String | |
| fn | Function | A callback function that is called with options, callback(err) |
***
<a name="beforefind"></a>
## `beforeFind(name, fn)`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/hooks.js#L319)
A hook that is run before a find (select) query
**Params:**
| Name | Type | Description |
| ---- | ---- | ----------- |
| name | String | |
| fn | Function | A callback function that is called with options, callback(err) |
***
<a name="beforefindafterexpandincludeall"></a>
## `beforeFindAfterExpandIncludeAll(name, fn)`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/hooks.js#L328)
A hook that is run before a find (select) query, after any { include: {all: ...} } options are expanded
**Params:**
| Name | Type | Description |
| ---- | ---- | ----------- |
| name | String | |
| fn | Function | A callback function that is called with options, callback(err) |
***
<a name="beforefindafteroptions"></a>
## `beforeFindAfterOptions(name, fn)`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/hooks.js#L337)
A hook that is run before a find (select) query, after all option parsing is complete
**Params:**
| Name | Type | Description |
| ---- | ---- | ----------- |
| name | String | |
| fn | Function | A callback function that is called with options, callback(err) |
***
<a name="afterfind"></a>
## `afterFind(name, fn)`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/hooks.js#L346)
A hook that is run after a find (select) query
**Params:**
| Name | Type | Description |
| ---- | ---- | ----------- |
| name | String | |
| fn | Function | A callback function that is called with instance(s), options, callback(err) |
***
<a name="beforedefine"></a>
## `beforeDefine(name, fn)`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/hooks.js#L355)
A hook that is run before a define call
**Params:**
| Name | Type | Description |
| ---- | ---- | ----------- |
| name | String | |
| fn | Function | A callback function that is called with attributes, options, callback(err) |
***
<a name="afterdefine"></a>
## `afterDefine(name, fn)`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/hooks.js#L364)
A hook that is run after a define call
**Params:**
| Name | Type | Description |
| ---- | ---- | ----------- |
| name | String | |
| fn | Function | A callback function that is called with factory, callback(err) |
***
<a name="beforeinit"></a>
## `beforeInit(name, fn)`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/hooks.js#L373)
A hook that is run before Sequelize() call
**Params:**
| Name | Type | Description |
| ---- | ---- | ----------- |
| name | String | |
| fn | Function | A callback function that is called with config, options, callback(err) |
***
<a name="afterinit"></a>
## `afterInit(name, fn)`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/hooks.js#L382)
A hook that is run after Sequelize() call
**Params:**
| Name | Type | Description |
| ---- | ---- | ----------- |
| name | String | |
| fn | Function | A callback function that is called with sequelize, callback(err) |
***
_This document is automatically generated based on source code comments. Please do not edit it directly, as your changes will be ignored. Please write on <a href="irc://irc.freenode.net/#sequelizejs">IRC</a>, open an issue or a create a pull request if you feel something can be improved. For help on how to write source code documentation see [JSDoc](http://usejsdoc.org) and [dox](https://github.com/tj/dox)_
\ No newline at end of file
<a name="instance"></a>
# Class Instance
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/instance.js#L32)
This class represents an single instance, a database row. You might see it referred to as both Instance and instance. You should not
instantiate the Instance class directly, instead you access it using the finder and creation methods on the model.
Instance instances operate with the concept of a `dataValues` property, which stores the actual values represented by the instance.
By default, the values from dataValues can also be accessed directly from the Instance, that is:
```js
instance.field
// is the same as
instance.get('field')
// is the same as
instance.getDataValue('field')
```
However, if getters and/or setters are defined for `field` they will be invoked, instead of returning the value from `dataValues`.
Accessing properties directly or using `get` is preferred for regular use, `getDataValue` should only be used for custom getters.
**See:**
* [Sequelize#define](sequelize#define)
***
<a name="isnewrecord"></a>
## `isNewRecord` -> `Boolean`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/instance.js#L44)
Returns true if this instance has not yet been persisted to the database
***
<a name="model"></a>
## `Model()` -> `Model`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/instance.js#L53)
Returns the Model the instance was created from.
**See:**
* [Model](model)
***
<a name="sequelize"></a>
## `sequelize()` -> `Sequelize`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/instance.js#L62)
A reference to the sequelize instance
**See:**
* [Sequelize](sequelize)
***
<a name="isdeleted"></a>
## `isDeleted()` -> `Boolean`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/instance.js#L75)
If timestamps and paranoid are enabled, returns whether the deletedAt timestamp of this instance is set. Otherwise, always returns false.
***
<a name="values"></a>
## `values()` -> `Object`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/instance.js#L87)
Get the values of this Instance. Proxies to `this.get`
**See:**
* [Instance#get](instance#get)
***
<a name="isdirty"></a>
## `isDirty()` -> `Boolean`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/instance.js#L100)
A getter for `this.changed()`. Returns true if any keys have changed.
**See:**
* [Instance#changed](instance#changed)
***
<a name="primarykeyvalues"></a>
## `primaryKeyValues()` -> `Object`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/instance.js#L112)
Get the values of the primary keys of this instance.
***
<a name="getdatavalue"></a>
## `getDataValue(key)` -> `any`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/instance.js#L148)
Get the value of the underlying data value
**Params:**
| Name | Type | Description |
| ---- | ---- | ----------- |
| key | String | |
***
<a name="setdatavalue"></a>
## `setDataValue(key, value)`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/instance.js#L158)
Update the underlying data value
**Params:**
| Name | Type | Description |
| ---- | ---- | ----------- |
| key | String | |
| value | any | |
***
<a name="get"></a>
## `get([key], [options])` -> `Object|any`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/instance.js#L172)
If no key is given, returns all values of the instance, also invoking virtual getters.
If key is given and a field or virtual getter is present for the key it will call that getter - else it will return the value for key.
**Params:**
| Name | Type | Description |
| ---- | ---- | ----------- |
| [key] | String | |
| [options] | Object | |
| [options.plain=false] | Boolean | If set to true, included instances will be returned as plain objects |
***
<a name="set"></a>
## `set(key, value, [options])`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/instance.js#L251)
Set is used to update values on the instance (the sequelize representation of the instance that is, remember that nothing will be persisted before you actually call `save`).
In its most basic form `set` will update a value stored in the underlying `dataValues` object. However, if a custom setter function is defined for the key, that function
will be called instead. To bypass the setter, you can pass `raw: true` in the options object.
If set is called with an object, it will loop over the object, and call set recursively for each key, value pair. If you set raw to true, the underlying dataValues will either be
set directly to the object passed, or used to extend dataValues, if dataValues already contain values.
When set is called, the previous value of the field is stored, so that you can later see which fields changed (see `changed`).
Set can also be used to build instances for associations, if you have values for those. TODO - mick should probably write something here about how includes in set works - perhaps also even some tests?
**See:**
* [Model#find](model#find)
**Params:**
| Name | Type | Description |
| ---- | ---- | ----------- |
| key | String &#124; Object | |
| value | any | |
| [options] | Object | |
| [options.raw=false] | Boolean | If set to true, field and virtual setters will be ignored |
| [options.reset=false] | Boolean | Clear all previously set data values |
| [options.include] | Object | |
__Aliases:__ setAttributes
***
<a name="changed"></a>
## `changed([key])` -> `Boolean|Array`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/instance.js#L373)
If changed is called with a string it will return a boolean indicating whether the value of that key in `dataValues` is different from the value in `_previousDataValues`.
If changed is called without an argument, it will return an array of keys that have changed.
**Params:**
| Name | Type | Description |
| ---- | ---- | ----------- |
| [key] | String | |
***
<a name="previous"></a>
## `previous(key)` -> `any`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/instance.js#L392)
Returns the previous value for key from `_previousDataValues`.
**Params:**
| Name | Type | Description |
| ---- | ---- | ----------- |
| key | String | |
***
<a name="save"></a>
## `save([fields], [options])` -> `Promise<this|Errors.ValidationError>`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/instance.js#L453)
Validate this instance, and if the validation passes, persist it to the database.
On success, the callback will be called with this instance. On validation error, the callback will be called with an instance of `Sequelize.ValidationError`.
This error will have a property for each of the fields for which validation failed, with the error message for that field.
**Params:**
| Name | Type | Description |
| ---- | ---- | ----------- |
| [fields] | Array | An optional array of strings, representing database columns. If fields is provided, only those columns will be validation and saved. |
| [options] | Object | |
| [options.fields] | Object | An alternative way of setting which fields should be persisted |
| [options.silent=false] | Boolean | If true, the updatedAt timestamp will not be updated. |
| [options.transaction] | Transaction | |
***
<a name="reload"></a>
## `reload([options])` -> `Promise<this>`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/instance.js#L663)
Refresh the current instance in-place, i.e. update the object with current data from the DB and return the same object.
This is different from doing a `find(Instance.id)`, because that would create and return a new instance. With this method,
all references to the Instance are updated with the new data and no new objects are created.
**See:**
* [Model#find](model#find)
**Params:**
| Name | Type | Description |
| ---- | ---- | ----------- |
| [options] | Object | Options that are passed on to `Model.find` |
***
<a name="validate"></a>
## `validate([options])` -> `Promise<undefined|Errors.ValidationError>`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/instance.js#L690)
Validate the attribute of this instance according to validation rules set in the model definition.
Emits null if and only if validation successful; otherwise an Error instance containing { field name : [error msgs] } entries.
**See:**
* [InstanceValidator](instancevalidator)
**Params:**
| Name | Type | Description |
| ---- | ---- | ----------- |
| [options] | Object | Options that are passed to the validator |
| [options.skip] | Array | An array of strings. All properties that are in this array will not be validated |
***
<a name="updateattributes"></a>
## `updateAttributes(updates, options)` -> `Promise<this>`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/instance.js#L710)
This is the same as calling `setAttributes`, then calling `save`.
**See:**
* [Instance#setAttributes](instance#setattributes)
* [Instance#save](instance#save)
**Params:**
| Name | Type | Description |
| ---- | ---- | ----------- |
| updates | Object | See `setAttributes` |
| options | Object | See `save` |
***
<a name="destroy"></a>
## `destroy([options={}])` -> `Promise<undefined>`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/instance.js#L731)
Destroy the row corresponding to this instance. Depending on your setting for paranoid, the row will either be completely deleted, or have its deletedAt timestamp set to the current time.
**Params:**
| Name | Type | Description |
| ---- | ---- | ----------- |
| [options={}] | Object | |
| [options.force=false] | Boolean | If set to true, paranoid models will actually be deleted |
***
<a name="restore"></a>
## `restore([options={}])` -> `Promise<undefined>`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/instance.js#L772)
Restore the row corresponding to this instance. Only available for paranoid models.
**Params:**
| Name | Type | Description |
| ---- | ---- | ----------- |
| [options={}] | Object | |
***
<a name="increment"></a>
## `increment(fields, [options])` -> `Promise`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/instance.js#L820)
Increment the value of one or more columns. This is done in the database, which means it does not use the values currently stored on the Instance. The increment is done using a
```sql
SET column = column + X
```
query. To get the correct value after an increment into the Instance you should do a reload.
```js
instance.increment('number') // increment number by 1
instance.increment(['number', 'count'], { by: 2 }) // increment number and count by 2
instance.increment({ answer: 42, tries: 1}, { by: 2 }) // increment answer by 42, and tries by 1.
// `by` is ignored, since each column has its own value
```
**See:**
* [Instance#reload](instance#reload)
**Params:**
| Name | Type | Description |
| ---- | ---- | ----------- |
| fields | String &#124; Array|Object | If a string is provided, that column is incremented by the value of `by` given in options. If an array is provided, the same is true for each column. If and object is provided, each column is incremented by the value given |
| [options] | Object | |
| [options.by=1] | Integer | The number to increment by |
| [options.transaction=null] | Transaction | |
***
<a name="decrement"></a>
## `decrement(fields, [options])` -> `Promise`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/instance.js#L885)
Decrement the value of one or more columns. This is done in the database, which means it does not use the values currently stored on the Instance. The decrement is done using a
```sql
SET column = column - X
```
query. To get the correct value after an decrement into the Instance you should do a reload.
```js
instance.decrement('number') // decrement number by 1
instance.decrement(['number', 'count'], { by: 2 }) // decrement number and count by 2
instance.decrement({ answer: 42, tries: 1}, { by: 2 }) // decrement answer by 42, and tries by 1.
// `by` is ignored, since each column has its own value
```
**See:**
* [Instance#reload](instance#reload)
**Params:**
| Name | Type | Description |
| ---- | ---- | ----------- |
| fields | String &#124; Array|Object | If a string is provided, that column is decremented by the value of `by` given in options. If an array is provided, the same is true for each column. If and object is provided, each column is decremented by the value given |
| [options] | Object | |
| [options.by=1] | Integer | The number to decrement by |
| [options.transaction=null] | Transaction | |
***
<a name="equals"></a>
## `equals(other)` -> `Boolean`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/instance.js#L919)
Check whether all values of this and `other` Instance are the same
**Params:**
| Name | Type | Description |
| ---- | ---- | ----------- |
| other | Instance | |
***
<a name="equalsoneof"></a>
## `equalsOneOf(others)` -> `Boolean`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/instance.js#L939)
Check if this is eqaul to one of `others` by calling equals
**Params:**
| Name | Type | Description |
| ---- | ---- | ----------- |
| others | Array | |
***
<a name="tojson"></a>
## `toJSON()` -> `object`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/instance.js#L957)
Convert the instance to a JSON representation. Proxies to calling `get` with no keys. This means get all values gotten from the DB, and apply all custom getters.
**See:**
* [Instance#get](instance#get)
***
_This document is automatically generated based on source code comments. Please do not edit it directly, as your changes will be ignored. Please write on <a href="irc://irc.freenode.net/#sequelizejs">IRC</a>, open an issue or a create a pull request if you feel something can be improved. For help on how to write source code documentation see [JSDoc](http://usejsdoc.org) and [dox](https://github.com/tj/dox)_
\ No newline at end of file
<a name="model"></a>
# Class Model
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/model.js#L25)
A Model represents a table in the database. Sometimes you might also see it refererred to as model, or simply as factory. This class should _not_ be instantiated directly, it is created using `sequelize.define`, and already created models can be loaded using `sequelize.import`
### Mixes:
* Hooks
* Associations
***
<a name="removeattribute"></a>
## `removeAttribute([attribute])`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/model.js#L394)
Remove attribute from model definition
**Params:**
| Name | Type | Description |
| ---- | ---- | ----------- |
| [attribute] | String | |
***
<a name="sync"></a>
## `sync()` -> `Promise<this>`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/model.js#L404)
Sync this Model to the DB, that is create the table. Upon success, the callback will be called with the model instance (this)
**See:**
* [Sequelize#sync](sequelize#sync)
***
<a name="drop"></a>
## `drop([options])` -> `Promise`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/model.js#L440)
Drop the table represented by this Model
**Params:**
| Name | Type | Description |
| ---- | ---- | ----------- |
| [options] | Object | |
| [options.cascade=false] | Boolean | Also drop all objects depending on this table, such as views. Only works in postgres |
***
<a name="schema"></a>
## `schema(schema, [options])` -> `this`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/model.js#L457)
Apply a schema to this model. For postgres, this will actually place the schema in front of the table name - `"schema"."tableName"`,
while the schema will be prepended to the table name for mysql and sqlite - `'schema.tablename'`.
**Params:**
| Name | Type | Description |
| ---- | ---- | ----------- |
| schema | String | The name of the schema |
| [options] | Object | |
| [options.schemaDelimiter='.'] | String | The character(s) that separates the schema name from the table name |
***
<a name="gettablename"></a>
## `getTableName(options)` -> `String|Object`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/model.js#L480)
Get the tablename of the model, taking schema into account. The method will return The name as a string if the model has no schema,
or an object with `tableName`, `schema` and `delimiter` properties.
**Params:**
| Name | Type | Description |
| ---- | ---- | ----------- |
| options | Object | The hash of options from any query. You can use one model to access tables with matching schemas by overriding `getTableName` and using custom key/values to alter the name of the table. (eg. subscribers_1, subscribers_2) |
***
<a name="scope"></a>
## `scope(options*)` -> `Model`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/model.js#L523)
Apply a scope created in `define` to the model. First let's look at how to create scopes:
```js
var Model = sequelize.define('model', attributes, {
defaultScope: {
where: {
username: 'dan'
},
limit: 12
},
scopes: {
isALie: {
where: {
stuff: 'cake'
}
},
complexFunction: function(email, accessLevel) {
return {
where: ['email like ? AND access_level >= ?', email + '%', accessLevel]
}
},
}
})
```
Now, since you defined a default scope, every time you do Model.find, the default scope is appended to your query. Here's a couple of examples:
```js
Model.findAll() // WHERE username = 'dan'
Model.findAll({ where: { age: { gt: 12 } } }) // WHERE age > 12 AND username = 'dan'
```
To invoke scope functions you can do:
```js
Model.scope({ method: ['complexFunction' 'dan@sequelize.com', 42]}).findAll()
// WHERE email like 'dan@sequelize.com%' AND access_level >= 42
```
**Params:**
| Name | Type | Description |
| ---- | ---- | ----------- |
| options* | Array &#124; Object|String|null | The scope(s) to apply. Scopes can either be passed as consecutive arguments, or as an array of arguments. To apply simple scopes, pass them as strings. For scope function, pass an object, with a `method` property. The value can either be a string, if the method does not take any arguments, or an array, where the first element is the name of the method, and consecutive elements are arguments to that method. Pass null to remove all scopes, including the default. |
__Returns:__ A reference to the model, with the scope(s) applied. Calling scope again on the returned model will clear the previous scope.
***
<a name="findall"></a>
## `findAll([options], [queryOptions])` -> `Promise<Array<Instance>>`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/model.js#L698)
Search for multiple instances.
__Simple search using AND and =__
```js
Model.find({
where: {
attr1: 42,
attr2: 'cake'
}
})
```
```sql
WHERE attr1 = 42 AND attr2 = 'cake'
```
__Using greater than, less than etc.__
```js
Model.find({
where: {
attr1: {
gt: 50
},
attr2: {
lte: 45
},
attr3: {
in: [1,2,3]
},
attr4: {
ne: 5
}
}
})
```
```sql
WHERE attr1 > 50 AND attr2 <= 45 AND attr3 IN (1,2,3) AND attr4 != 5
```
Possible options are: `gt, gte, lt, lte, ne, between/.., nbetween/notbetween/!.., in, not, like, nlike/notlike`
__Queries using OR__
```js
Model.find({
where: Sequelize.and(
{ name: 'a project' },
Sequelize.or(
{ id: [1,2,3] },
{ id: { gt: 10 } }
)
)
})
```
```sql
WHERE name = 'a project' AND (id` IN (1,2,3) OR id > 10)
```
The success listener is called with an array of instances if the query succeeds.
**See:**
* [Sequelize#query](sequelize#query)
**Params:**
| Name | Type | Description |
| ---- | ---- | ----------- |
| [options] | Object | A hash of options to describe the scope of the search |
| [options.where] | Object | A hash of attributes to describe your search. See above for examples. |
| [options.attributes] | Array&lt;String&gt; | A list of the attributes that you want to select. To rename an attribute, you can pass an array, with two elements - the first is the name of the attribute in the DB (or some kind of expression such as `Sequelize.literal`, `Sequelize.fn` and so on), and the second is the name you want the attribute to have in the returned instance |
| [options.paranoid=true] | Boolean | If false, will include columns which have a non-null deletedAt column. |
| [options.include] | Array&lt;Object &#124; Model&gt; | A list of associations to eagerly load using a left join. Supported is either `{ include: [ Model1, Model2, ...]}` or `{ include: [{ model: Model1, as: 'Alias' }]}`. If your association are set up with an `as` (eg. `X.hasMany(Y, { as: 'Z }`, you need to specify Z in the as attribute when eager loading Y). |
| [options.include[].model] | Model | The model you want to eagerly load |
| [options.include[].as] | String | The alias of the relation, in case the model you want to eagerly load is aliassed. For `hasOne` / `belongsTo`, this should be the singular name, and for `hasMany`, it should be the plural |
| [options.include[].association] | Association | The association you want to eagerly load. (This can be used instead of providing a model/as pair) |
| [options.include[].where] | Object | Where clauses to apply to the child models. Note that this converts the eager load to an inner join, unless you explicitly set `required: false` |
| [options.include[].attributes] | Array&lt;String&gt; | A list of attributes to select from the child model |
| [options.include[].required] | Boolean | If true, converts to an inner join, which means that the parent model will only be loaded if it has any matching children. True if `include.where` is set, false otherwise. |
| [options.include[].include] | Array&lt;Object &#124; Model&gt; | Load further nested related models |
| [options.order] | String &#124; Array|Sequelize.fn | Specifies an ordering. If a string is provided, it will be esacped. Using an array, you can provide several columns / functions to order by. Each element can be further wrapped in a two-element array. The first element is the column / function to order by, the second is the direction. For example: `order: [['name', 'DESC']]`. In this way the column will be escaped, but the direction will not. |
| [options.limit] | Number | |
| [options.offset] | Number | |
| [queryOptions] | Object | Set the query options, e.g. raw, specifying that you want raw data instead of built Instances. See sequelize.query for options |
| [queryOptions.transaction] | Transaction | |
| [queryOptions.lock] | String | Lock the selected rows in either share or update mode. Possible options are transaction.LOCK.UPDATE and transaction.LOCK.SHARE. See [transaction.LOCK for an example](https://github.com/sequelize/sequelize/wiki/API-Reference-Transaction#LOCK) |
__Aliases:__ all
***
<a name="findone"></a>
## `findOne([options], [queryOptions])` -> `Promise<Instance>`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/model.js#L785)
Search for a single instance. This applies LIMIT 1, so the listener will always be called with a single instance.
**See:**
* [Model#findAll](model#findall)
**Params:**
| Name | Type | Description |
| ---- | ---- | ----------- |
| [options] | Object &#124; Number | A hash of options to describe the scope of the search, or a number to search by id. |
| [queryOptions] | Object | |
__Aliases:__ find
***
<a name="aggregate"></a>
## `aggregate(field, aggregateFunction, [options])` -> `Promise<options.dataType>`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/model.js#L821)
Run an aggregation method on the specified field
**Params:**
| Name | Type | Description |
| ---- | ---- | ----------- |
| field | String | The field to aggregate over. Can be a field name or * |
| aggregateFunction | String | The function to use for aggregation, e.g. sum, max etc. |
| [options] | Object | Query options. See sequelize.query for full options |
| [options.dataType] | DataType &#124; String | The type of the result. If `field` is a field in this Model, the default will be the type of that field, otherwise defaults to float. |
| [options.distinct] | boolean | Applies DISTINCT to the field being aggregated over |
***
<a name="count"></a>
## `count([options])` -> `Promise<Integer>`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/model.js#L855)
Count the number of records matching the provided where clause.
If you provide an `include` option, the number of matching associations will be counted instead.
**Params:**
| Name | Type | Description |
| ---- | ---- | ----------- |
| [options] | Object | |
| [options.include] | Object | Include options. See `find` for details |
| [options.distinct] | boolean | Appliy COUNT(DISTINCT(col)) |
***
<a name="findandcountall"></a>
## `findAndCountAll([findOptions], [queryOptions])` -> `Promise<Object>`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/model.js#L892)
Find all the rows matching your query, within a specified offset / limit, and get the total number of rows matching your query. This is very usefull for paging
```js
Model.findAndCountAll({
where: ...,
limit: 12,
offset: 12
}).success(function (result) {
})
```
In the above example, `result.rows` will contain rows 13 through 24, while `result.count` will return the total number of rows that matched your query.
**See:**
* [Model#findAll](model#findall)
**Params:**
| Name | Type | Description |
| ---- | ---- | ----------- |
| [findOptions] | Object | See findAll |
| [queryOptions] | Object | See Sequelize.query |
***
<a name="max"></a>
## `max(field, [options])` -> `Promise<Any>`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/model.js#L922)
Find the maximum value of field
**See:**
* [Model#aggregate](model#aggregate)
**Params:**
| Name | Type | Description |
| ---- | ---- | ----------- |
| field | String | |
| [options] | Object | See aggregate |
***
<a name="min"></a>
## `min(field, [options])` -> `Promise<Any>`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/model.js#L935)
Find the minimum value of field
**See:**
* [Model#aggregate](model#aggregate)
**Params:**
| Name | Type | Description |
| ---- | ---- | ----------- |
| field | String | |
| [options] | Object | See aggregate |
***
<a name="sum"></a>
## `sum(field, [options])` -> `Promise<Number>`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/model.js#L948)
Find the sum of field
**See:**
* [Model#aggregate](model#aggregate)
**Params:**
| Name | Type | Description |
| ---- | ---- | ----------- |
| field | String | |
| [options] | Object | See aggregate |
***
<a name="build"></a>
## `build(values, [options])` -> `Instance`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/model.js#L964)
Builds a new model instance. Values is an object of key value pairs, must be defined but can be empty.
**Params:**
| Name | Type | Description |
| ---- | ---- | ----------- |
| values | Object | |
| [options] | Object | |
| [options.raw=false] | Boolean | If set to true, values will ignore field and virtual setters. |
| [options.isNewRecord=true] | Boolean | |
| [options.isDirty=true] | Boolean | |
| [options.include] | Array | an array of include options - Used to build prefetched/included model instances. See `set` |
***
<a name="create"></a>
## `create(values, [options])` -> `Promise<Instance>`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/model.js#L1033)
Builds a new model instance and calls save on it.
**See:**
* [Instance#build](instance#build)
* [Instance#save](instance#save)
**Params:**
| Name | Type | Description |
| ---- | ---- | ----------- |
| values | Object | |
| [options] | Object | |
| [options.raw=false] | Boolean | If set to true, values will ignore field and virtual setters. |
| [options.isNewRecord=true] | Boolean | |
| [options.isDirty=true] | Boolean | |
| [options.fields] | Array | If set, only columns matching those in fields will be saved |
| [options.include] | Array | an array of include options - Used to build prefetched/included model instances |
| [options.transaction] | Transaction | |
***
<a name=""></a>
## `(options)` -> `Promise<Instance>`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/model.js#L1064)
Find a row that matches the query, or build (but don't save) the row if none is found.
The successfull result of the promise will be (instance, initialized) - Make sure to use .spread()
**Params:**
| Name | Type | Description |
| ---- | ---- | ----------- |
| options | Object | |
| options.where | Object | A hash of search attributes. |
| [options.defaults] | Object | Default values to use if building a new instance |
| [options.transaction] | Object | Transaction to run query under |
__Aliases:__ findOrBuild
***
<a name="findorcreate"></a>
## `findOrCreate(options, [queryOptions])` -> `Promise<Instance|created>`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/model.js#L1109)
Find a row that matches the query, or build and save the row if none is found
The successfull result of the promise will be (instance, created) - Make sure to use .spread()
If no transaction is passed in the `queryOptions` object, a new transaction will be created internally, to prevent the race condition where a matching row is created by another connection after the find but before the insert call.
However, it is not always possible to handle this case in SQLite, specifically if one transaction inserts and another tries to select before the first one has comitted. In this case, an instance of sequelize.TimeoutError will be thrown instead.
If a transaction is created, a savepoint will be created instead, and any unique constraint violation will be handled internally.
**Params:**
| Name | Type | Description |
| ---- | ---- | ----------- |
| options | Object | |
| options.where | Object | where A hash of search attributes. |
| [options.defaults] | Object | Default values to use if creating a new instance |
| [queryOptions] | Object | Options passed to the find and create calls |
***
<a name="bulkcreate"></a>
## `bulkCreate(records, [options])` -> `Promise<Array<Instance>>`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/model.js#L1183)
Create and insert multiple instances in bulk.
The success handler is passed an array of instances, but please notice that these may not completely represent the state of the rows in the DB. This is because MySQL
and SQLite do not make it easy to obtain back automatically generated IDs and other default values in a way that can be mapped to multiple records.
To obtain Instances for the newly created values, you will need to query for them again.
**Params:**
| Name | Type | Description |
| ---- | ---- | ----------- |
| records | Array | List of objects (key/value pairs) to create instances from |
| [options] | Object | |
| [options.fields] | Array | Fields to insert (defaults to all fields) |
| [options.validate=false] | Boolean | Should each row be subject to validation before it is inserted. The whole insert will fail if one row fails validation |
| [options.hooks=true] | Boolean | Run before / after bulk create hooks? |
| [options.individualHooks=false] | Boolean | Run before / after create hooks for each individual Instance? BulkCreate hooks will still be run if options.hooks is true. |
| [options.ignoreDuplicates=false] | Boolean | Ignore duplicate values for primary keys? (not supported by postgres) |
***
<a name="destroy"></a>
## `destroy()` -> `Promise<undefined>`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/model.js#L1334)
Delete multiple instances, or set their deletedAt timestamp to the current time if `paranoid` is enabled.
**Params:**
| Name | Type | Description |
| ---- | ---- | ----------- |
| [options.where] | Object | Filter the destroy |
| [options.hooks=true] | Boolean | Run before / after bulk destroy hooks? |
| [options.individualHooks=false] | Boolean | If set to true, destroy will find all records within the where parameter and will execute before / after bulkDestroy hooks on each row |
| [options.limit] | Number | How many rows to delete |
| [options.force=false] | Boolean | Delete instead of setting deletedAt to current timestamp (only applicable if `paranoid` is enabled) |
| [options.truncate=false] | Boolean | If set to true, dialects that support it will use TRUNCATE instead of DELETE FROM. If a table is truncated the where and limit options are ignored |
| [options.cascade=false] | Boolean | Only used in conjuction with TRUNCATE. Truncates all tables that have foreign-key references to the named table, or to any tables added to the group due to CASCADE. |
***
<a name="restore"></a>
## `restore()` -> `Promise<undefined>`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/model.js#L1401)
Restore multiple instances if `paranoid` is enabled.
**Params:**
| Name | Type | Description |
| ---- | ---- | ----------- |
| [options.where] | Object | Filter the restore |
| [options.hooks=true] | Boolean | Run before / after bulk restore hooks? |
| [options.individualHooks=false] | Boolean | If set to true, restore will find all records within the where parameter and will execute before / after bulkRestore hooks on each row |
| [options.limit] | Number | How many rows to undelete |
***
<a name="update"></a>
## `update(values, options)` -> `Promise<Array<affectedCount|affectedRows>>`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/model.js#L1470)
Update multiple instances that match the where options. The promise returns an array with one or two elements. The first element is always the number
of affected rows, while the second element is the actual affected rows (only supported in postgres with `options.returning` true.)
**Params:**
| Name | Type | Description |
| ---- | ---- | ----------- |
| values | Object | |
| options | Object | |
| options.where | Object | Options to describe the scope of the search. |
| [options.validate=true] | Boolean | Should each row be subject to validation before it is inserted. The whole insert will fail if one row fails validation |
| [options.hooks=true] | Boolean | Run before / after bulk update hooks? |
| [options.individualHooks=false] | Boolean | Run before / after update hooks? |
| [options.returning=false] | Boolean | Return the affected rows (only for postgres) |
| [options.limit] | Number | How many rows to update (only for mysql and mariadb) |
***
<a name="describe"></a>
## `describe()` -> `Promise`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/model.js#L1626)
Run a describe query on the table. The result will be return to the listener as a hash of attributes and their types.
***
<a name="dataset"></a>
## `dataset()` -> `node-sql`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/model.js#L1637)
A proxy to the node-sql query builder, which allows you to build your query through a chain of method calls.
The returned instance already has all the fields property populated with the field of the model.
**See:**
__Returns:__ A node-sql instance
***
_This document is automatically generated based on source code comments. Please do not edit it directly, as your changes will be ignored. Please write on <a href="irc://irc.freenode.net/#sequelizejs">IRC</a>, open an issue or a create a pull request if you feel something can be improved. For help on how to write source code documentation see [JSDoc](http://usejsdoc.org) and [dox](https://github.com/tj/dox)_
\ No newline at end of file
<a name="promise"></a>
# Class Promise
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/promise.js#L25)
A slightly modified version of bluebird promises. This means that, on top of the methods below, you can also call all the methods listed on the link below.
The main difference is that sequelize promises allows you to attach a listener that will be called with the generated SQL, each time a query is run.
The sequelize promise class works seamlessly with other A+/thenable libraries, with one exception.
If you want to propagate SQL events across `then`, `all` calls etc., you must use sequelize promises exclusively.
### Mixes:
* https://github.com/petkaantonov/bluebird/blob/master/API.md
***
<a name="on"></a>
## `on(evt, fct)`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/promise.js#L110)
Listen for events, event emitter style. Mostly for backwards compat. with EventEmitter
**Deprecated**
**Params:**
| Name | Type | Description |
| ---- | ---- | ----------- |
| evt | String | |
| fct | Function | |
***
<a name="emit"></a>
## `emit(type, value(s)*)`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/promise.js#L131)
Emit an event from the emitter
**Deprecated**
**Params:**
| Name | Type | Description |
| ---- | ---- | ----------- |
| type | string | The type of event |
| value(s)* | any | All other arguments will be passed to the event listeners |
***
<a name="success"></a>
## `success(onSuccess)` -> `this`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/promise.js#L169)
Listen for success events.
```js
promise.success(function (result) {
//...
});
```
**Deprecated**
**Params:**
| Name | Type | Description |
| ---- | ---- | ----------- |
| onSuccess | function | |
__Aliases:__ ok
***
<a name="error"></a>
## `error(onError)` -> `this`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/promise.js#L196)
Listen for error events
```js
promise.error(function (err) {
//...
});
```
**Deprecated**
**Params:**
| Name | Type | Description |
| ---- | ---- | ----------- |
| onError | function | |
__Aliases:__ fail, failure
***
<a name="done"></a>
## `done(onDone)` -> `this`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/promise.js#L219)
Listen for both success and error events.
```js
promise.done(function (err, result) {
//...
});
```
**Deprecated** done(fct) is deprecated, done() is regular promise syntax to explicitly signal the end of a promise chain and will not be deprecated
**Params:**
| Name | Type | Description |
| ---- | ---- | ----------- |
| onDone | function | |
__Aliases:__ complete
***
<a name="sql"></a>
## `sql(onSQL)` -> `this`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/promise.js#L244)
Attach a function that is called every time the function that created this emitter executes a query.
**Params:**
| Name | Type | Description |
| ---- | ---- | ----------- |
| onSQL | function | |
***
<a name="proxy"></a>
## `proxy(promise, [options])` -> `this`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/promise.js#L259)
Proxy every event of this promise to another one.
**Deprecated**
**Params:**
| Name | Type | Description |
| ---- | ---- | ----------- |
| promise | SequelizePromise | The promise that should receive the events. |
| [options] | Object | |
| [options.events] | Array | An array of the events to proxy. Defaults to sql, error and success |
***
_This document is automatically generated based on source code comments. Please do not edit it directly, as your changes will be ignored. Please write on <a href="irc://irc.freenode.net/#sequelizejs">IRC</a>, open an issue or a create a pull request if you feel something can be improved. For help on how to write source code documentation see [JSDoc](http://usejsdoc.org) and [dox](https://github.com/tj/dox)_
\ No newline at end of file
<a name="sequelize"></a>
# Class Sequelize
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/sequelize.js#L34)
This is the main class, the entry point to sequelize. To use it, you just need to import sequelize:
```js
var Sequelize = require('sequelize');
```
In addition to sequelize, the connection library for the dialect you want to use should also be installed in your project. You don't need to import it however, as sequelize will take care of that.
***
<a name="sequelize"></a>
## `new Sequelize(database, [username=null], [password=null], [options={}])`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/sequelize.js#L91)
Instantiate sequelize with name of database, username and password
#### Example usage
```javascript
// without password and options
var sequelize = new Sequelize('database', 'username')
// without options
var sequelize = new Sequelize('database', 'username', 'password')
// without password / with blank password
var sequelize = new Sequelize('database', 'username', null, {})
// with password and options
var sequelize = new Sequelize('my_database', 'john', 'doe', {})
// with uri (see below)
var sequelize = new Sequelize('mysql://localhost:3306/database', {})
```
**Params:**
| Name | Type | Description |
| ---- | ---- | ----------- |
| database | String | The name of the database |
| [username=null] | String | The username which is used to authenticate against the database. |
| [password=null] | String | The password which is used to authenticate against the database. |
| [options={}] | Object | An object with options. |
| [options.dialect='mysql'] | String | The dialect you of the database you are connecting to. One of mysql, postgres, sqlite and mariadb |
| [options.dialectModulePath=null] | String | If specified, load the dialect library from this path. For example, if you want to use pg.js instead of pg when connecting to a pg database, you should specify 'pg.js' here |
| [options.dialectOptions] | Object | An object of additional options, which are passed directly to the connection library |
| [options.storage] | String | Only used by sqlite. Defaults to ':memory:' |
| [options.host='localhost'] | String | The host of the relational database. |
| [options.port=] | Integer | The port of the relational database. |
| [options.protocol='tcp'] | String | The protocol of the relational database. |
| [options.define={}] | Object | Default options for model definitions. See sequelize.define for options |
| [options.query={}] | Object | Default options for sequelize.query |
| [options.set={}] | Object | Default options for sequelize.set |
| [options.sync={}] | Object | Default options for sequelize.sync |
| [options.timezone='+00:00'] | String | The timezone used when converting a date from the database into a javascript date. The timezone is also used to SET TIMEZONE when connecting to the server, to ensure that the result of NOW, CURRENT_TIMESTAMP and other time related functions have in the right timezone. For best cross platform performance use the format +/-HH:MM. |
| [options.logging=console.log] | Function | A function that gets executed everytime Sequelize would log something. |
| [options.omitNull=false] | Boolean | A flag that defines if null values should be passed to SQL queries or not. |
| [options.queue=true] | Boolean | Queue queries, so that only maxConcurrentQueries number of queries are executing at once. If false, all queries will be executed immediately. |
| [options.maxConcurrentQueries=50] | Integer | The maximum number of queries that should be executed at once if queue is true. |
| [options.native=false] | Boolean | A flag that defines if native library shall be used or not. Currently only has an effect for postgres |
| [options.replication=false] | Boolean | Use read / write replication. To enable replication, pass an object, with two properties, read and write. Write should be an object (a single server for handling writes), and read an array of object (several servers to handle reads). Each read/write server can have the following properties: `host`, `port`, `username`, `password`, `database` |
| [options.pool={}] | Object | Should sequelize use a connection pool. Default is true |
| [options.pool.maxConnections] | Integer | |
| [options.pool.minConnections] | Integer | |
| [options.pool.maxIdleTime] | Integer | The maximum time, in milliseconds, that a connection can be idle before being released |
| [options.pool.validateConnection] | Function | A function that validates a connection. Called with client. The default function checks that client is an object, and that its state is not disconnected |
| [options.quoteIdentifiers=true] | Boolean | Set to `false` to make table names and attributes case-insensitive on Postgres and skip double quoting of them. |
***
<a name="sequelize"></a>
## `new Sequelize(uri, [options={}])`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/sequelize.js#L100)
Instantiate sequlize with an URI
**Params:**
| Name | Type | Description |
| ---- | ---- | ----------- |
| uri | String | A full database URI |
| [options={}] | object | See above for possible options |
***
<a name="models"></a>
## `models`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/sequelize.js#L195)
Models are stored here under the name given to `sequelize.define`
***
<a name="sequelize"></a>
## `Sequelize`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/sequelize.js#L211)
A reference to Sequelize constructor from sequelize. Useful for accessing DataTypes, Errors etc.
**See:**
* [Sequelize](sequelize)
***
<a name="utils"></a>
## `Utils`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/sequelize.js#L218)
A reference to sequelize utilities. Most users will not need to use these utils directly. However, you might want to use `Sequelize.Utils._`, which is a reference to the lodash library, if you don't already have it imported in your project.
**See:**
* [Utils](utils)
***
<a name="promise"></a>
## `Promise`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/sequelize.js#L225)
A modified version of bluebird promises, that allows listening for sql events
**See:**
* [Promise](promise)
***
<a name="validator"></a>
## `Validator`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/sequelize.js#L234)
Exposes the validator.js object, so you can extend it with custom validation functions. The validator is exposed both on the instance, and on the constructor.
**See:**
***
<a name="transaction"></a>
## `Transaction`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/sequelize.js#L254)
A reference to the sequelize transaction class. Use this to access isolationLevels when creating a transaction
**See:**
* [Transaction](transaction)
* [Sequelize#transaction](sequelize#transaction)
***
<a name="instance"></a>
## `Instance`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/sequelize.js#L261)
A reference to the sequelize instance class.
**See:**
* [Instance](instance)
***
<a name="error"></a>
## `Error`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/sequelize.js#L275)
A general error class
**See:**
* [Errors#BaseError](errors#baseerror)
***
<a name="validationerror"></a>
## `ValidationError`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/sequelize.js#L283)
Emitted when a validation fails
**See:**
* [Errors#ValidationError](errors#validationerror)
***
<a name="validationerroritem"></a>
## `ValidationErrorItem`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/sequelize.js#L291)
Describes a validation error on an instance path
**See:**
* [Errors#ValidationErrorItem](errors#validationerroritem)
***
<a name="databaseerror"></a>
## `DatabaseError`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/sequelize.js#L298)
A base class for all database related errors.
**See:**
* [Errors#DatabaseError](errors#databaseerror)
***
<a name="timeouterror"></a>
## `TimeoutError`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/sequelize.js#L305)
Thrown when a database query times out because of a deadlock
**See:**
* [Errors#TimeoutError](errors#timeouterror)
***
<a name="uniqueconstrainterror"></a>
## `UniqueConstraintError`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/sequelize.js#L312)
Thrown when a unique constraint is violated in the database
**See:**
* [Errors#UniqueConstraintError](errors#uniqueconstrainterror)
***
<a name="foreignkeyconstrainterror"></a>
## `ForeignKeyConstraintError`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/sequelize.js#L319)
Thrown when a foreign key constraint is violated in the database
**See:**
* [Errors#ForeignKeyConstraintError](errors#foreignkeyconstrainterror)
***
<a name="getdialect"></a>
## `getDialect()` -> `String`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/sequelize.js#L327)
Returns the specified dialect.
__Returns:__ The specified dialect.
***
<a name="getqueryinterface"></a>
## `getQueryInterface()` -> `QueryInterface`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/sequelize.js#L339)
Returns an instance of QueryInterface.
**See:**
* [QueryInterface](queryinterface)
__Returns:__ An instance (singleton) of QueryInterface.
***
<a name="getmigrator"></a>
## `getMigrator([options={}], [force=false])` -> `Migrator`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/sequelize.js#L353)
Returns an instance (singleton) of Migrator.
**See:**
* [Migrator](migrator)
**Params:**
| Name | Type | Description |
| ---- | ---- | ----------- |
| [options={}] | Object | See Migrator for options |
| [force=false] | Boolean | A flag that defines if the migrator should get instantiated or not. |
__Returns:__ An instance of Migrator.
***
<a name="define"></a>
## `define(modelName, attributes, [options])` -> `Model`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/sequelize.js#L461)
Define a new model, representing a table in the DB.
The table columns are define by the hash that is given as the second argument. Each attribute of the hash represents a column. A short table definition might look like this:
```js
sequelize.define('modelName', {
columnA: {
type: Sequelize.BOOLEAN,
validate: {
is: ["[a-z]",'i'], // will only allow letters
max: 23, // only allow values <= 23
isIn: {
args: [['en', 'zh']],
msg: "Must be English or Chinese"
}
},
field: 'column_a'
// Other attributes here
},
columnB: Sequelize.STRING,
columnC: 'MY VERY OWN COLUMN TYPE'
})
sequelize.models.modelName // The model will now be available in models under the name given to define
```
As shown above, column definitions can be either strings, a reference to one of the datatypes that are predefined on the Sequelize constructor, or an object that allows you to specify both the type of the column, and other attributes such as default values, foreign key constraints and custom setters and getters.
For a list of possible data types, see http://sequelizejs.com/docs/latest/models#data-types
For more about getters and setters, see http://sequelizejs.com/docs/latest/models#getters---setters
For more about instance and class methods, see http://sequelizejs.com/docs/latest/models#expansion-of-models
For more about validation, see http://sequelizejs.com/docs/latest/models#validations
**See:**
* [DataTypes](datatypes)
* [Hooks](hooks)
**Params:**
| Name | Type | Description |
| ---- | ---- | ----------- |
| modelName | String | The name of the model. The model will be stored in `sequelize.models` under this name |
| attributes | Object | An object, where each attribute is a column of the table. Each column can be either a DataType, a string or a type-description object, with the properties described below: |
| attributes.column | String &#124; DataType|Object | The description of a database column |
| attributes.column.type | String &#124; DataType | A string or a data type |
| [attributes.column.allowNull=true] | Boolean | If false, the column will have a NOT NULL constraint, and a not null validation will be run before an instance is saved. |
| [attributes.column.defaultValue=null] | Any | A literal default value, a javascript function, or an SQL function (see `sequelize.fn`) |
| [attributes.column.unique=false] | String &#124; Boolean | If true, the column will get a unique constraint. If a string is provided, the column will be part of a composite unique index. If multiple columns have the same string, they will be part of the same unique index |
| [attributes.column.primaryKey=false] | Boolean | |
| [attributes.column.field=null] | String | If set, sequelize will map the attribute name to a different name in the database |
| [attributes.column.autoIncrement=false] | Boolean | |
| [attributes.column.comment=null] | String | |
| [attributes.column.references] | String &#124; Model | If this column references another table, provide it here as a Model, or a string |
| [attributes.column.referencesKey='id'] | String | The column of the foreign table that this column references |
| [attributes.column.onUpdate] | String | What should happen when the referenced key is updated. One of CASCADE, RESTRICT, SET DEFAULT, SET NULL or NO ACTION |
| [attributes.column.onDelete] | String | What should happen when the referenced key is deleted. One of CASCADE, RESTRICT, SET DEFAULT, SET NULL or NO ACTION |
| [attributes.column.get] | Function | Provide a custom getter for this column. Use `this.getDataValue(String)` to manipulate the underlying values. |
| [attributes.column.set] | Function | Provide a custom setter for this column. Use `this.setDataValue(String, Value)` to manipulate the underlying values. |
| [attributes.validate] | Object | An object of validations to execute for this column every time the model is saved. Can be either the name of a validation provided by validator.js, a validation function provided by extending validator.js (see the `DAOValidator` property for more details), or a custom validation function. Custom validation functions are called with the value of the field, and can possibly take a second callback argument, to signal that they are asynchronous. If the validator is sync, it should throw in the case of a failed validation, it it is async, the callback should be called with the error text. |
| [options] | Object | These options are merged with the default define options provided to the Sequelize constructor |
| [options.defaultScope] | Object | Define the default search scope to use for this model. Scopes have the same form as the options passed to find / findAll |
| [options.scopes] | Object | More scopes, defined in the same way as defaultScope above. See `Model.scope` for more information about how scopes are defined, and what you can do with them |
| [options.omitNull] | Boolean | Don't persits null values. This means that all columns with null values will not be saved |
| [options.timestamps=true] | Boolean | Adds createdAt and updatedAt timestamps to the model. |
| [options.paranoid=false] | Boolean | Calling `destroy` will not delete the model, but instead set a `deletedAt` timestamp if this is true. Needs `timestamps=true` to work |
| [options.underscored=false] | Boolean | Converts all camelCased columns to underscored if true |
| [options.underscoredAll=false] | Boolean | Converts camelCased model names to underscored tablenames if true |
| [options.freezeTableName=false] | Boolean | If freezeTableName is true, sequelize will not try to alter the DAO name to get the table name. Otherwise, the dao name will be pluralized |
| [options.name] | Object | An object with two attributes, `singular` and `plural`, which are used when this model is associated to others. |
| [options.name.singular=inflection.singularize(modelName)] | String | |
| [options.name.plural=inflection.pluralize(modelName)] | String | |
| [options.indexes] | Array&lt;Object&gt; | |
| [options.indexes[].name] | String | The name of the index. Defaults to model name + _ + fields concatenated |
| [options.indexes[].type] | String | Index type. Only used by mysql. One of `UNIQUE`, `FULLTEXT` and `SPATIAL` |
| [options.indexes[].method] | String | The method to create the index by (`USING` statement in SQL). BTREE and HASH are supported by mysql and postgres, and postgres additionally supports GIST and GIN. |
| [options.indexes[].unique=false] | Boolean | Should the index by unique? Can also be triggered by setting type to `UNIQUE` |
| [options.indexes[].concurrently=false] | Boolean | PostgreSQL will build the index without taking any write locks. Postgres only |
| [options.indexes[].fields] | Array&lt;String &#124; Object&gt; | An array of the fields to index. Each field can either be a string containing the name of the field, or an object with the following attributes: `attribute` (field name), `length` (create a prefix index of length chars), `order` (the direction the column should be sorted in), `collate` (the collation (sort order) for the column) |
| [options.createdAt] | String &#124; Boolean | Override the name of the createdAt column if a string is provided, or disable it if false. Timestamps must be true |
| [options.updatedAt] | String &#124; Boolean | Override the name of the updatedAt column if a string is provided, or disable it if false. Timestamps must be true |
| [options.deletedAt] | String &#124; Boolean | Override the name of the deletedAt column if a string is provided, or disable it if false. Timestamps must be true |
| [options.tableName] | String | Defaults to pluralized model name, unless freezeTableName is true, in which case it uses model name verbatim |
| [options.getterMethods] | Object | Provide getter functions that work like those defined per column. If you provide a getter method with the same name as a column, it will be used to access the value of that column. If you provide a name that does not match a column, this function will act as a virtual getter, that can fetch multiple other values |
| [options.setterMethods] | Object | Provide setter functions that work like those defined per column. If you provide a setter method with the same name as a column, it will be used to update the value of that column. If you provide a name that does not match a column, this function will act as a virtual setter, that can act on and set other values, but will not be persisted |
| [options.instanceMethods] | Object | Provide functions that are added to each instance (DAO). If you override methods provided by sequelize, you can access the original method using `this.constructor.super_.prototype`, e.g. `this.constructor.super_.prototype.toJSON.apply(this, arguments)` |
| [options.classMethods] | Object | Provide functions that are added to the model (Model). If you override methods provided by sequelize, you can access the original method using `this.constructor.prototype`, e.g. `this.constructor.prototype.find.apply(this, arguments)` |
| [options.schema='public'] | String | |
| [options.engine] | String | |
| [options.charset] | String | |
| [options.comment] | String | |
| [options.collate] | String | |
| [options.hooks] | Object | An object of hook function that are called before and after certain lifecycle events. The possible hooks are: beforeValidate, afterValidate, beforeBulkCreate, beforeBulkDestroy, beforeBulkUpdate, beforeCreate, beforeDestroy, beforeUpdate, afterCreate, afterDestroy, afterUpdate, afterBulkCreate, afterBulkDestory and afterBulkUpdate. See Hooks for more information about hook functions and their signatures. Each property can either be a function, or an array of functions. |
| [options.validate] | Object | An object of model wide validations. Validations have access to all model values via `this`. If the validator function takes an argument, it is asumed to be async, and is called with a callback that accepts an optional error. |
***
<a name="model"></a>
## `model(modelName)` -> `Model`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/sequelize.js#L513)
Fetch a DAO factory which is already defined
**Params:**
| Name | Type | Description |
| ---- | ---- | ----------- |
| modelName | String | The name of a model defined with Sequelize.define |
***
<a name="isdefined"></a>
## `isDefined(modelName)` -> `Boolean`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/sequelize.js#L527)
Checks whether a model with the given name is defined
**Params:**
| Name | Type | Description |
| ---- | ---- | ----------- |
| modelName | String | The name of a model defined with Sequelize.define |
***
<a name="import"></a>
## `import(path)` -> `Model`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/sequelize.js#L541)
Imports a model defined in another file
Imported models are cached, so multiple calls to import with the same path will not load the file multiple times
See https://github.com/sequelize/sequelize/blob/master/examples/using-multiple-model-files/Task.js for a short example of how to define your models in separate files so that they can be imported by sequelize.import
**Params:**
| Name | Type | Description |
| ---- | ---- | ----------- |
| path | String | The path to the file that holds the model you want to import. If the part is relative, it will be resolved relatively to the calling file |
***
<a name="query"></a>
## `query(sql, [callee], [options={}], [replacements])` -> `Promise`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/sequelize.js#L581)
Execute a query on the DB, with the posibility to bypass all the sequelize goodness.
If you do not provide other arguments than the SQL, raw will be assumed to the true, and sequelize will not try to do any formatting to the results of the query.
**See:**
* [Model#build](model#build)
**Params:**
| Name | Type | Description |
| ---- | ---- | ----------- |
| sql | String | |
| [callee] | Instance | If callee is provided, the returned data will be put into the callee |
| [options={}] | Object | Query options. |
| [options.raw] | Boolean | If true, sequelize will not try to format the results of the query, or build an instance of a model from the result |
| [options.transaction=null] | Transaction | The transaction that the query should be executed under |
| [options.type='SELECT'] | String | The type of query you are executing. The query type affects how results are formatted before they are passed back. If no type is provided sequelize will try to guess the right type based on the sql, and fall back to SELECT. The type is a string, but `Sequelize.QueryTypes` is provided is convenience shortcuts. Current options are SELECT, BULKUPDATE and BULKDELETE |
| [options.nest=false] | Boolean | If true, transforms objects with `.` separated property names into nested objects using [dottie.js](https://github.com/mickhansen/dottie.js). For example { 'user.username': 'john' } becomes { user: { username: 'john' }} |
| [replacements] | Object &#124; Array | Either an object of named parameter replacements in the format `:param` or an array of unnamed replacements to replace `?` in your SQL. |
***
<a name="set"></a>
## `set(variables, options)` -> `Promise`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/sequelize.js#L627)
Execute a query which would set an environment or user variable. The variables are set per connection, so this function needs a transaction.
Only works for MySQL.
**Params:**
| Name | Type | Description |
| ---- | ---- | ----------- |
| variables | Object | Object with multiple variables. |
| options | Object | Query options. |
| options.transaction | Transaction | The transaction that the query should be executed under |
***
<a name="createschema"></a>
## `createSchema(schema)` -> `Promise`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/sequelize.js#L665)
Create a new database schema.
Note,that this is a schema in the [postgres sense of the word](http://www.postgresql.org/docs/9.1/static/ddl-schemas.html),
not a database table. In mysql and sqlite, this command will do nothing.
**See:**
* [Model#schema](model#schema)
**Params:**
| Name | Type | Description |
| ---- | ---- | ----------- |
| schema | String | Name of the schema |
***
<a name="showallschemas"></a>
## `showAllSchemas()` -> `Promise`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/sequelize.js#L676)
Show all defined schemas
Note,that this is a schema in the [postgres sense of the word](http://www.postgresql.org/docs/9.1/static/ddl-schemas.html),
not a database table. In mysql and sqlite, this will show all tables.
***
<a name="dropschema"></a>
## `dropSchema(schema)` -> `Promise`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/sequelize.js#L688)
Drop a single schema
Note,that this is a schema in the [postgres sense of the word](http://www.postgresql.org/docs/9.1/static/ddl-schemas.html),
not a database table. In mysql and sqlite, this drop a table matching the schema name
**Params:**
| Name | Type | Description |
| ---- | ---- | ----------- |
| schema | String | Name of the schema |
***
<a name="dropallschemas"></a>
## `dropAllSchemas()` -> `Promise`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/sequelize.js#L699)
Drop all schemas
Note,that this is a schema in the [postgres sense of the word](http://www.postgresql.org/docs/9.1/static/ddl-schemas.html),
not a database table. In mysql and sqlite, this is the equivalent of drop all tables.
***
<a name="sync"></a>
## `sync([options={}])` -> `Promise`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/sequelize.js#L713)
Sync all defined DAOs to the DB.
**Params:**
| Name | Type | Description |
| ---- | ---- | ----------- |
| [options={}] | Object | |
| [options.force=false] | Boolean | If force is true, each DAO will do DROP TABLE IF EXISTS ..., before it tries to create its own table |
| [options.match] | RegEx | Match a regex against the database name before syncing, a safety check for cases where force: true is used in tests but not live code |
| [options.logging=console.log] | Boolean &#124; function | A function that logs sql queries, or false for no logging |
| [options.schema='public'] | String | The schema that the tables should be created in. This can be overriden for each table in sequelize.define |
***
<a name="drop"></a>
## `drop(options)` -> `Promise`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/sequelize.js#L758)
Drop all tables defined through this sequelize instance. This is done by calling Model.drop on each model
**See:**
* [Model#drop](model#drop)
**Params:**
| Name | Type | Description |
| ---- | ---- | ----------- |
| options | object | The options passed to each call to Model.drop |
***
<a name="authenticate"></a>
## `authenticate()` -> `Promise`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/sequelize.js#L780)
Test the connection by trying to authenticate
__Aliases:__ validate
***
<a name="fn "></a>
## `fn (fn, args)` -> `Sequelize.fn`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/sequelize.js#L811)
Creates a object representing a database function. This can be used in search queries, both in where and order parts, and as default values in column definitions.
If you want to refer to columns in your function, you should use `sequelize.col`, so that the columns are properly interpreted as columns and not a strings.
Convert a user's username to upper case
```js
instance.updateAttributes({
username: self.sequelize.fn('upper', self.sequelize.col('username'))
})
```
**See:**
* [Model#find](model#find)
* [Model#findAll](model#findall)
* [Model#define](model#define)
* [Sequelize#col](sequelize#col)
**Params:**
| Name | Type | Description |
| ---- | ---- | ----------- |
| fn | String | The function you want to call |
| args | any | All further arguments will be passed as arguments to the function |
***
<a name="col"></a>
## `col(col)` -> `Sequelize.col`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/sequelize.js#L824)
Creates a object representing a column in the DB. This is often useful in conjunction with `sequelize.fn`, since raw string arguments to fn will be escaped.
**See:**
* [Sequelize#fn](sequelize#fn)
**Params:**
| Name | Type | Description |
| ---- | ---- | ----------- |
| col | String | The name of the column |
***
<a name="cast"></a>
## `cast(val, type)` -> `Sequelize.cast`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/sequelize.js#L838)
Creates a object representing a call to the cast function.
**Params:**
| Name | Type | Description |
| ---- | ---- | ----------- |
| val | any | The value to cast |
| type | String | The type to cast it to |
***
<a name="literal"></a>
## `literal(val)` -> `Sequelize.literal`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/sequelize.js#L851)
Creates a object representing a literal, i.e. something that will not be escaped.
**Params:**
| Name | Type | Description |
| ---- | ---- | ----------- |
| val | any | |
__Aliases:__ asIs
***
<a name="and"></a>
## `and(args)` -> `Sequelize.and`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/sequelize.js#L864)
An AND query
**See:**
* [Model#find](model#find)
**Params:**
| Name | Type | Description |
| ---- | ---- | ----------- |
| args | String &#124; Object | Each argument will be joined by AND |
***
<a name="or"></a>
## `or(args)` -> `Sequelize.or`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/sequelize.js#L877)
An OR query
**See:**
* [Model#find](model#find)
**Params:**
| Name | Type | Description |
| ---- | ---- | ----------- |
| args | String &#124; Object | Each argument will be joined by OR |
***
<a name="json"></a>
## `json(conditions, [value])` -> `Sequelize.json`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/sequelize.js#L890)
Creates an object representing nested where conditions for postgres's json data-type.
**See:**
* [Model#find](model#find)
**Params:**
| Name | Type | Description |
| ---- | ---- | ----------- |
| conditions | String &#124; Object | A hash containing strings/numbers or other nested hash, a string using dot notation or a string using postgres json syntax. |
| [value] | String &#124; Number|Boolean | An optional value to compare against. Produces a string of the form "<json path> = '<value>'". |
***
<a name="where"></a>
## `where(attr, [comparator='='], logic)` -> `Sequelize.where`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/sequelize.js#L912)
A way of specifying attr = condition.
The attr can either be an object taken from `Model.rawAttributes` (for example `Model.rawAttributes.id` or `Model.rawAttributes.name`). The
attribute should be defined in your model definition. The attribute can also be an object from one of the sequelize utility functions (`sequelize.fn`, `sequelize.col` etc.)
For string attributes, use the regular `{ where: { attr: something }}` syntax. If you don't want your string to be escaped, use `sequelize.literal`.
**See:**
* [Model#find](model#find)
**Params:**
| Name | Type | Description |
| ---- | ---- | ----------- |
| attr | Object | The attribute, which can be either an attribute object from `Model.rawAttributes` or a sequelize object, for example an instance of `sequelize.fn`. For simple string attributes, use the POJO syntax |
| [comparator='='] | string | |
| logic | String &#124; Object | The condition. Can be both a simply type, or a further condition (`.or`, `.and`, `.literal` etc.) |
__Aliases:__ condition
***
<a name="transaction"></a>
## `transaction([options={}])` -> `Promise`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/sequelize.js#L953)
Start a transaction. When using transactions, you should pass the transaction in the options argument in order for the query to happen under that transaction
```js
sequelize.transaction().then(function (t) {
return User.find(..., { transaction: t}).then(function (user) {
return user.updateAttributes(..., { transaction: t});
})
.then(t.commit.bind(t))
.catch(t.rollback.bind(t));
})
```
A syntax for automatically committing or rolling back based on the promise chain resolution is also supported:
```js
sequelize.transaction(function (t) { // Note that we use a callback rather than a promise.then()
return User.find(..., { transaction: t}).then(function (user) {
return user.updateAttributes(..., { transaction: t});
});
}).then(function () {
// Commited
}).catch(function (err) {
// Rolled back
console.error(err);
});
```
**See:**
* [Transaction](transaction)
**Params:**
| Name | Type | Description |
| ---- | ---- | ----------- |
| [options={}] | Object | |
| [options.autocommit=true] | Boolean | |
| [options.isolationLevel='REPEATABLE | String | READ'] See `Sequelize.Transaction.ISOLATION_LEVELS` for possible options |
***
_This document is automatically generated based on source code comments. Please do not edit it directly, as your changes will be ignored. Please write on <a href="irc://irc.freenode.net/#sequelizejs">IRC</a>, open an issue or a create a pull request if you feel something can be improved. For help on how to write source code documentation see [JSDoc](http://usejsdoc.org) and [dox](https://github.com/tj/dox)_
\ No newline at end of file
<a name="transaction"></a>
# Class Transaction
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/transaction.js#L12)
The transaction object is used to identify a running transaction. It is created by calling `Sequelize.transaction()`.
To run a query under a transaction, you should pass the transaction in the options object.
***
<a name="isolation_levels"></a>
## `ISOLATION_LEVELS`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/transaction.js#L45)
The possible isolations levels to use when starting a transaction
```js
{
READ_UNCOMMITTED: "READ UNCOMMITTED",
READ_COMMITTED: "READ COMMITTED",
REPEATABLE_READ: "REPEATABLE READ",
SERIALIZABLE: "SERIALIZABLE"
}
```
***
<a name="lock"></a>
## `LOCK`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/transaction.js#L67)
Possible options for row locking. Used in conjuction with `find` calls:
```js
t1 // is a transaction
Model.findAll({
where: ...
}, {
transaction: t1,
lock: t1.LOCK.UPDATE,
lock: t1.LOCK.SHARE
})
```
***
<a name="commit"></a>
## `commit()` -> `this`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/transaction.js#L77)
Commit the transaction
***
<a name="rollback"></a>
## `rollback()` -> `this`
[View code](https://github.com/sequelize/sequelize/blob/5aa77fa291abeaf0498f65724000c75da9ab9028/lib/transaction.js#L97)
Rollback (abort) the transaction
***
_This document is automatically generated based on source code comments. Please do not edit it directly, as your changes will be ignored. Please write on <a href="irc://irc.freenode.net/#sequelizejs">IRC</a>, open an issue or a create a pull request if you feel something can be improved. For help on how to write source code documentation see [JSDoc](http://usejsdoc.org) and [dox](https://github.com/tj/dox)_
\ No newline at end of file
<script type="text/javascript">
fromGithub = function (partialId, ext) {
ext = ext || '';
var $partial = $("#" + partialId)
$.get("https://cdn.rawgit.com/sequelize/express-example/master/" + partialId.replace("_", "/") + ext, function (code) {
if (ext === '.js') {
code = hljs.highlight('js', code).value;
}
code = '<div class="highlight"><pre>' + code + '</pre></div>';
$partial.replaceWith(code);
}, 'html');
}
</script>
## Introduction
This article explains the usage of Sequelize with the MVC framework Express.You will learn how and where to define models and how to load them when needed.
## A minimal express application
In order to create a minimal express application, we need to install express first and scaffold a project. We can do this via the following commands:
```bash
$ mkdir example-app
$ cd example-app
$ npm install express express-generator
$ node_modules/.bin/express . -f
$ npm install
$ ./bin/www
```
You should now be able to see a tiny welcome page on `http://localhost:3000`
## Adding Sequelize to the application
Now that we have the express application in place, we can start adding Sequelize to it. What we need for that are the following packages: sequelize, sequelize-cli, sqlite3. Please note, that for the sake of simplicity this tutorial will use SQLite.
```bash
$ npm install --save sequelize@2.0.0-rc1 sequelize-cli sqlite3
```
This will install the respective packages and uses the upcoming major release of sequelize. We can now let the sequelize CLI initialize the project's directory:
```bash
$ node_modules/.bin/sequelize init
```
Running this command will create the folders `config`, `migrations` and `models`.
## Implementing a todo app
As an example application we will create a very basic and simple todo tool, which allows the creation of users and the management of their tasks.
### bin/www
In order to create a maintainable application, we will put all the database logic into the `models` folder. When the application gets fired up, sequelize will sync the models with the database and afterwards start the server. This way we don't clutter the application while making use of sequelize's features.
<div id="bin_www"></div>
<script>$(function () { fromGithub("bin_www") })</script>
### models/index.js
This file has been generated with the sequelize CLI and collects all the models from the `models` directory and associates them if needed.
<div id="models_index"></div>
<script>$(function () { fromGithub("models_index", '.js') })</script>
### models/user.js
All models of our application are located as separate files in the `models` folder. If you want to add a new model, just add it to this folder and everything will work automagically. Also you can use the sequelize CLI's `sequelize model:create`.
**Notice** that the `associate` method receives a parameter `models`, which contains every declared model within the models directory.
<div id="models_user"></div>
<script>$(function () { fromGithub("models_user", '.js') })</script>
### models/task.js
The other needed model is `Task`. It relates to the `User`.
<div id="models_task"></div>
<script>$(function () { fromGithub("models_task", '.js') })</script>
### routes/index.js
The file `routes/index.js` contains the logic for a request against the main homepage. It loads the models module and uses it to load all the users and tasks from the database.
<div id="routes_index"></div>
<script>$(function () { fromGithub("routes_index", '.js') })</script>
This will allow us to iterate over the users in the view file. We will skip the rest of the route files for this article.
### views/index.jade
As we passed the users to the view and include the tasks for each user, we can access the data in the view's template file. Besides listing the users and tasks, there are also forms for creating new instances.
<div id="views_index"></div>
<script>$(function () { fromGithub("views_index", '.jade') })</script>
## What's next?
This article shows a basic approach of how to integrate Sequelize into an ExpressJS application. It allows the very easy management of models by adding new files to a specific folder. Starting the application will automatically sync the schema with the database.
If you don't want to have automatic schema synchronization and instead want migrations, just add a respective step to your deployment script. When you use the CLI for the model generation, you will gain the migration scripts for free as well.
You can find the complete application code [on Github](https://github.com/sequelize/express-example). Feel free to add pull requests to it.
Besides the use of Sequelize as model backend in your ExpressJS application, you might also want to turn your server into a restful API. If that is the case, check out [the repository on Github](https://github.com/sequelize/sequelize-restful)
\ No newline at end of file
## Introduction
This article explains the basic concepts of Sequelize. You will learn how to use the supported dialects, which ways of database setup approaches are available and how common scenarios can be achieved.
## Premise
We will skip the very basic things and directly dive into the Sequelize related stuff. Here is a list of things that have to be in place before you can start:
* Node.JS at v0.8 or higher
* One of the supported databases / SQLite bindings
* The credentials for the respective database
* A basic understanding of how databases are working
* Optional but recommended: Coffee :)
## A word about promises
TODO - a link to bluebird + general promise syntax + catch / error handling
## Setting up a project
Now that your computer is prepared and your coffee sits next to your keyboard,
we can finally get started. First things first: Create a directory and initializeit with NPM!
```bash
$ mkdir my-project
$ cd my-project
$ npm init
```
NPM will ask you a couple of questions. Answer them or just hit the return key until it's satisfied.
Once done, you can install Sequelize and the connector for your database of choice.
```bash
$ npm install --save sequelize
$ npm install --save pg # for postgres
$ npm install --save mysql # for mysql
$ npm install --save sqlite3 # for sqlite
$ npm install --save mariasql # for mariasql
```
## Connecting to the database
Open the created directory in your favorite text editor and add a new file called `app.js` with the following content.
```js
var Sequelize = require('sequelize')
, sequelize = new Sequelize('database_name', 'username', 'password', {
dialect: "mysql", // or 'sqlite', 'postgres', 'mariadb'
port: 3306, // or 5432 (for postgres)
});
sequelize
.authenticate()
.then(function(err) {
console.log('Connection has been established successfully.');
}, function (err) {
console.log('Unable to connect to the database:', err);
});
```
## Managing the schema of your database
Sequelize supports two way of schema management. You can either define so called migrations, which are programmatically changing your database's structure. Or you can let Sequelize create the tables for you.
While the first possibility of using `migrations` takes more time to setup, it's most likely the way to go, if you want to deploy your application on many different server environments. The reason for that is based on the fact, that migrations are consistently changing your database according to the current state of the schema.
However, the automated way of using Sequelize's function `sequelize.sync` will probably be a good choice on your local machine or if you just want to quickly spin up a prototype.
As this article is for beginners, we will skip migrations for now and take a closer look at the automated way.
### Defining a model
In order to let Sequelize create a schemas in the database, you need to describe, what kind of data you want to store. This can be done with `sequelize.define`:
```js
var User = sequelize.define('User', {
username: Sequelize.STRING,
password: Sequelize.STRING
});
```
This will define a user model that has a username and password. Furthermore, Sequelize will automatically add the columns `id`, `createdAt` and `updatedAt`. `createdAt` and `updatedAt` are controlled by sequelize - when you `create` a model through sequelize `createdAt` will be set, and whenever you call `updateAttributes` / `save` on a model, `updatedAt` will be set.
### Synchronizing the schema
As we want to store data in the database, we need to create a representation of the model.
```js
sequelize
.sync({ force: true })
.then(function(err) {
console.log('It worked!');
}, function (err) {
console.log('An error occurred while creating the table:', err);
});
```
Once executed, the database will contain a table `Users` (note the plural) with the columns:
* id - INT(11)
* username - VARCHAR(255)
* password - VARCHAR(255)
* createdAt - DATETIME
* updatedAt - DATETIME
Please note, that `{ force: true }` will drop the `Users` table and re-create it.
### Configuration
You might not need the timestamps or you might not want the plural of the model's name as table name, right? Luckily there are configuration possibilities for that.
```js
var User = sequelize.define('User', {
username: Sequelize.STRING,
password: Sequelize.STRING
}, {
tableName: 'my_user_table', // this will define the table's name
timestamps: false // this will deactivate the timestamp columns
})
```
And just in case you want to customize the timestamp field names, you can do it like this:
```js
var User = sequelize.define('User', {
username: Sequelize.STRING,
password: Sequelize.STRING
}, {
updatedAt: 'last_update',
createdAt: 'date_of_creation'
})
```
Furthermore you can introduce a `deletedAt` timestamp so models are not actually deleted when you call `destroy`. Adding a `deletedAt` timestamp is called making the model 'paranoid':
```js
var User = sequelize.define('User', {
username: Sequelize.STRING,
password: Sequelize.STRING
}, {
paranoid: true
});
```
## Creating and persisting instances
Sequelize allows the creation of instances in two ways. You can either `build` an object and `save` it afterwards. Or you can directly `create` an instance in the database:
```js
var user = User.build({
username: 'john-doe',
password: generatePasswordHash('i-am-so-great')
})
user.save().then(function() {
/* ... */
})
```
This persists the instance in a two step way. If you want to do everything at once, use the following approach:
```js
User.create({
username: 'john-doe',
password: generatePasswordHash('i-am-so-great')
}).then(function(user) {
/* ... */
})
```
## Reading data from the database
Every defined model has finder methods, with which you can read the database. Searching for a single item can be done with `Model.find`. Retrieval of multiple items needs the use of `Model.findAll`.
```js
User
.find({ where: { username: 'john-doe' } })
.then(function(err, johnDoe) {
if (!johnDoe) {
console.log('No user with the username "john-doe" has been found.');
} else {
console.log('Hello ' + johnDoe.username + '!');
console.log('All attributes of john:', johnDoe.get());
}
});
```
Please note that there won't be any error if no user with the name "john-doe" has been found. This is intended, as there is not internal or authentication error.
## Defining associations
A very common use case is the definition of associations between two or even more models. Once declared, Sequelize will know how to query the database to get or set associated data. Furthermore it will be able to automatically create the respective foreign key columns for you.
Before taking a closer look at the code, it is critical to understand some details about the three different association types.
### One to one
An association between one source and one target is called "one to one" or 1:1 association. It consists of a source that **has one** target and a target that **belongs to** a source.
Sequelize expects a foreign key in the target's schema. That means that there has to be an attribute respectively a column in the target's table.
```js
var Source = sequelize.define('Source', {})
, Target = sequelize.define('Target', {})
Source.hasOne(Target)
Target.belongsTo(Source)
sequelize
.sync({ force: true })
.then(function() {
// Even if we didn't define any foreign key or something else,
// instances of Target will have a column SourceId!
});
```
### One to many
An association between one source and many target is called "one to many" or 1:N association. It consists of a source that **has many** targets and some targets which **belong to** a source.
Sequelize expects a foreign key in the target's schema. That means that there has to be an attribute respectively a column in the target's table.
```js
var Source = sequelize.define('Source', {})
, Target = sequelize.define('Target', {})
Source.hasMany(Target)
Target.belongsTo(Source)
sequelize
.sync({ force: true })
.then(function() {
// Even if we didn't define any foreign key or something else,
// instances of Target will have a column SourceId!
})
```
### Many to many
An association between many sources and many targets is called "many to many" or N:M association. It consists of sources which **have many** targets and some targets which **have many** sources.
Sequelize expects a junction table which contains a foreign key to the source table and a foreign key to the target table. A row in the table connects a source with a target.
```js
var Source = sequelize.define('Source', {})
, Target = sequelize.define('Target', {})
Source.hasMany(Target)
Target.hasMany(Source)
sequelize
.sync({ force: true })
.then(function() {
// Even if we didn't define any foreign key or something else,
// Sequelize will create a table SourcesTargets.
})
```
### Getting/Setting associations
Defining associations is nice, but won't give you any advantage if you cannot read or set associations. Of course Sequelize will add respective functions to your models. Depending on the type of association you will find different methods:
```js
var Source = sequelize.define('Source', {})
, Target = sequelize.define('Target', {});
Source.hasOne(Target);
Target.belongsTo(Source);
sequelize.Promise.all([
Source.create({}),
Target.create({})
]).spread(function (source, target) {
// Set the association
return source.setTarget(target).return(source);
}).then(function(source) {
// Get the association
return source.getTarget();
}).then(function(_target) {
console.log(_target.values)
/*
{
id: 1,
createdAt: Sun Dec 08 2013 11:46:42 GMT+0100 (CET),
updatedAt: Sun Dec 08 2013 11:46:42 GMT+0100 (CET),
SourceId: 1
}
*/
});
```
### Clearing associations
Assuming we already defined the models (as in the previous code example) and synced the schema with the database, we can clear the associations like this:
```js
source.setTarget(null).then(function() {
return source.getTarget();
}).then(function(target) {
console.log(target);
});
```
### Adding / removing associations
For 1:N and N:M associations it makes sense to not only set the associations, but also to add or remove associations. Furthermore checking for an association can be handy.
```js
var Source = sequelize.define('Source', {})
, Target = sequelize.define('Target', {});
Source.hasMany(Target);
Target.belongsTo(Source);
return sequelize.Promise.all([
Source.create({}),
Target.create({});
Target.create({}),
]).bind({}).spread(function (source, target1, target2) {
// Set the association
this.source = source;
this.target1 = target1;
this.target2 = target2;
return source.setTargets([target1, target2]);
}).then(function() {
// Get the association
return this.source.getTargets();
}).then(function(targets) {
console.log(targets.length) // = 2
// Remove an association
return this.source.removeTarget(this.target1);
}).then(function() {
return source.getTargets();
}).then(function(targets) {
console.log(targets.length) // = 1
// Check for an association
return this.source.hasTarget(this.target1);
}).then(function(hasTarget) {
console.log(hasTarget) // false
// Adding an association
return this.source.addTarget(this.target1);
}).then(function() {
return this.source.getTargets();
}).then(function(targets) {
console.log(targets.length) // = 2
return this.source.hasTarget(this.target1);
}).then(function(hasTarget) {
console.log(hasTarget) // true
});
```
## A combined example
Now that you know the basics of Sequelize, you might want to see everything in a single program.
```js
var Sequelize = require('sequelize')
, sequelize = new Sequelize('database_name', 'username', 'password')
, User = sequelize.define('User', {
username: Sequelize.STRING,
password: Sequelize.STRING
});
sequelize.sync({ force: true }).then(function() {
return User.create({ username: 'john', password: '1111' });
}).then(function(user1) {
return User.find({ username: 'john' })
}).then(function(user2) {
console.log(user2.get()); // Get returns a JSON representation of the user
});
```
## What's next?
As there are some more advanced features in Sequelize which are a bit inappropriate for this article, you can check the following resources for further advice:
* [Migrations][0]
* [Data types][1]
* [Configuration of the model][2]
* [Validations][3]
* [Finders][4]
* [Associations][5]
[0]: /docs/latest/migrations
[1]: /docs/latest/models#data-types
[2]: /docs/latest/models#configuration
[3]: /docs/latest/models#validations
[4]: /docs/latest/models#finders
[5]: /docs/latest/associations
\ No newline at end of file
## Introduction
This section covers the use of Sequelize on Heroku. It will explain how to get started with Heroku and what is necessary to setup a proper environment. We will use MySQL on the development machine and PostgreSQL on the remote servers.
## Getting started with Heroku
Before we can roll out any software on the Heroku cluster, we need to sign up and have to connect our development environment. Here are the most basic steps:
* [Sign up][0] for a Heroku account.
* [Install][1] the Heroku Toolbelt. This tool will let you create applications and is a handy way to configure them on the command line.
* Use the new binary to login. Run the following command on command line:`heroku login`
And that's it. You should now be able to do things like `heroku apps`. This should list all applications you've currently created on the Heroku cluster. If you've just created a new account, this should show you an empty list. [You can get further information about the registration process here][2].
## A minimal express application
In order to create a minimal express application, we need to install express first. We can do this via the following commands:
```bash
$ mkdir example-app
$ cd example-app
$ npm install express
$ node_modules/.bin/express . -f
$ npm install
$ node app.js
```
So now we have a default express application. If you point your browser to `http://localhost:8080`, you will see a tiny page welcoming you.
Next step: Deploy the application to Heroku.
## Deployment to Heroku
First of all, we need to add the right version of Node.JS and NPM to the `package.json`. The file should look similiar to this:
```js
{
"name": "application-name",
"version": "0.0.1",
"private": true,
"scripts": {
"start": "node app.js"
},
"dependencies": {
"express": "3.1.1",
"jade": "*"
},
"engines": {
"node": "0.8.x",
"npm": "1.1.x"
}
}
```
Now we can create a Heroku application and deploy to it:
```bash
$ echo "web: node app.js" > Procfile
$ echo "node_modules" > .gitignore
$ git init
$ git add .
$ git commit -m "initial commit"
$ heroku create
$ git push heroku master
$ heroku ps:scale web=1
$ heroku open
```
You should now see a browser with the same application as on your local machine.
## Spawning a database on Heroku
In order to get a database on Heroku we can use their CLI. Just run the following command and take a closer look at it's output:
```bash
$ heroku addons:add heroku-postgresql:dev
```
This will result in something like this:
```bash
Adding heroku-postgresql:dev on fast-dusk-7858... done, v5 (free)
Attached as HEROKU_POSTGRESQL_BRONZE_URL
Database has been created and is available
! This database is empty. If upgrading, you can transfer
! data from another database with pgbackups:restore.
Use `heroku addons:docs heroku-postgresql:dev` to view documentation.
```
What we will need is the color (sounds strange right?) of the database. In this case we just created a `bronze` one. That means, that we will have an environment variable `HEROKU_POSTGRESQL_BRONZE_URL` containing the URI of the database.
If you are interested in the URI, you can just run this command:
```bash
$ heroku config:get HEROKU_POSTGRESQL_BRONZE_URL
$ # => postgres://pfforbjhkrletg:aic5oO6Cran1g3hk6mJa5QqNZB@ec2-23-21-91-97.compute-1.amazonaws.com:5432/dek11b2j1g3mfb
```
## Adding Sequelize to the application
The following commands will install `sequelize`, the needed PostgreSQL library as well as the MySQL bindings. Also we will create a folder `models`, that will contain the model definitions.
```bash
$ npm install --save sequelize pg mysql
$ mkdir models
```
### app.js
In order to create a maintainable application, we will put all the database logic into the `models` folder. The application's main file will then just sync the models with the database and run the server. This way we don't clutter the application.
```js
var express = require('express')
, routes = require('./routes')
, user = require('./routes/user')
, http = require('http')
, path = require('path')
, db = require('./models');
var app = express();
// all environments
app.set('port', process.env.PORT || 3000);
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(app.router);
app.use(express.static(path.join(__dirname, 'public')));
// development only
if ('development' === app.get('env')) {
app.use(express.errorHandler());
}
app.get('/', routes.index);
app.get('/users', user.list);
db.sequelize.sync().then(function() {
http.createServer(app).listen(app.get('port'), function(){
console.log('Express server listening on port ' + app.get('port'));
});
});
```
### models/index.js
The idea of this file is to configure a connection to the database and to collect all model definitions. Once everything is in place we will store the stuff in a singleton. This will make it possible to load the file whenever we need database access without running into issues with duplicated database access.
This file will also differ between the local machine and the Heroku server.
```js
if (!global.hasOwnProperty('db')) {
var Sequelize = require('sequelize')
, sequelize = null
if (process.env.HEROKU_POSTGRESQL_BRONZE_URL) {
// the application is executed on Heroku ... use the postgres database
sequelize = new Sequelize(process.env.HEROKU_POSTGRESQL_BRONZE_URL, {
dialect: 'postgres',
protocol: 'postgres',
port: match[4],
host: match[3],
logging: true //false
})
} else {
// the application is executed on the local machine ... use mysql
sequelize = new Sequelize('example-app-db', 'root', null)
}
global.db = {
Sequelize: Sequelize,
sequelize: sequelize,
User: sequelize.import(__dirname + '/user') 
// add your other models here
}
/*
Associations can be defined here. E.g. like this:
global.db.User.hasMany(global.db.SomethingElse)
*/
}
module.exports = global.db
```
### models/user.js
All the other models of our application will be located as separate files in the `models` folder. We will use the `import`-method of Sequelize to load those files.
```js
module.exports = function(sequelize, DataTypes) {
return sequelize.define("User", {
username: DataTypes.STRING
})
}
```
## Running Migrations
To run migrations on Heroku you must have the following entry in your config/config.json file:
```js
"production": {
"use_env_variable": "DATABASE_URL"
}
```
Which also means you must make sure your Heroku environment has [a promoted database.][3] Then from the command line run
```bash
$ heroku run bash
$ sequelize -m
```
## tl;dr
This article explains a straight-forward but maintainable approach for hosting an express application on Heroku. If you don't want to read all the stuff mentioned, just execute the following stuff and have fun.
```bash
$ mkdir example-app
$ cd example-app
$ npm install express
$ node_modules/.bin/express . -f
$ npm install
$ curl -s https://gist.github.com/sdepold/ced7d2a4a847f38901ef/raw/459c923dd0a14841c932bb95ff3be8a8170bd563/package.json > package.json
$ echo "web: node app.js" > Procfile
$ echo "node_modules" > .gitignore
$ npm install --save sequelize pg mysql
$ mkdir models
$ git init
$ git add .
$ git commit -m "initial commit"
$ heroku create
$ git push heroku master
$ heroku ps:scale web=1
$ heroku addons:add heroku-postgresql:dev
$ curl -s https://gist.github.com/sdepold/ced7d2a4a847f38901ef/raw/6db41e130a8b901cd0843bf52390b7cb11db5f15/app.js > app.js
$ curl -s https://gist.github.com/sdepold/ced7d2a4a847f38901ef/raw/26c5a94d74db4a242464b02aa8e0ae4b3bac6880/models-index.js > models/index.js
$ curl -s https://gist.github.com/sdepold/ced7d2a4a847f38901ef/raw/3b37b0e5d459b2e4b3833a63a018b600a1001795/models-user.js > models/user.js
$ clear
$ # Now run the following command and change HEROKU_POSTGRESQL_BRONZE_URL in
$ # the file "models/index.js" to its result:
$ heroku config|grep HEROKU_POSTGRESQL|cut -d : -f 1
$ git add .
$ git commit -m "sequelize application"
$ git push heroku master
$ heroku open
```
[0]: https://api.heroku.com/signup/devcenter
[1]: https://toolbelt.heroku.com/
[2]: https://devcenter.heroku.com/articles/quickstart
[3]: https://devcenter.heroku.com/articles/heroku-postgresql#establish-primary-db
\ No newline at end of file
table {
width:100%;
}
th:nth-child(1),
td:nth-child(1) {
width: 35%;
word-break: break-all;
}
td:nth-child(2),
td:nth-child(2) {
width: 20%;
word-break: break-word;
}
td,
th {
padding: 6px 13px;
border: 1px solid #ddd;
}
tr:nth-child(2n) {
background-color: #f8f8f8;
}
\ No newline at end of file
......@@ -11,20 +11,9 @@ program
.version('0.0.2')
.option('-f, --file [file]', 'Process a single file', '')
.option('-a, --all', 'Process all files, generate index etc. (default if no options are specified')
.option('-c, --clean', 'Remove all generated markdown and HTML files')
.option('-o --out [dir]', '', path.dirname(__filename))
.option('-o --out [dir]', '', path.dirname(__filename) + '/api')
.parse(process.argv);
if (program.clean) {
fs.readdirSync('docs/').forEach(function (file) {
if (file !== 'index.md' && path.extname(file) === '.md') {
fs.unlinkSync ('docs/' + file);
}
});
return;
}
var files;
if (program.file) {
files = [{file: program.file, output: 'tmp'}];
......
With Sequelize you can also specify associations between multiple classes&period; Doing so will help you to easily access and set those associated objects&period; The library therefore provides for each defined class different methods&comma; which are explained in the following chapters&period;
**Note&colon; **Associations with models that use custom primaryKeys &lpar;so not the field 'id'&rpar; are currently unsupported&period;
## One-To-One associations
One-To-One associations are connecting one source with exactly one target&period; In order to define a proper database schema&comma; Sequelize utilizes the methods `belongsTo` and `hasOne`&period; You can use them as follows&colon;
```js
var User = sequelize.define('User', {/* ... */})
var Project = sequelize.define('Project', {/* ... */})
 
// One-way associations
Project.hasOne(User)
 
/*
In this example hasOne will add an attribute ProjectId to the User model!
Furthermore, Project.prototype will gain the methods getUser and setUser according
to the first parameter passed to define. If you have underscore style
enabled, the added attribute will be project_id instead of ProjectId.
 
You can also define the foreign key, e.g. if you already have an existing
database and want to work on it:
*/
 
Project.hasOne(User, { foreignKey: 'initiator_id' })
 
/*
Because Sequelize will use the model's name (first parameter of define) for
the accessor methods, it is also possible to pass a special option to hasOne:
*/
 
Project.hasOne(User, { as: 'Initiator' })
// Now you will get Project#getInitiator and Project#setInitiator
 
// Or let's define some self references
var Person = sequelize.define('Person', { /* ... */})
 
Person.hasOne(Person, {as: 'Father'})
// this will add the attribute FatherId to Person
 
// also possible:
Person.hasOne(Person, {as: 'Father', foreignKey: 'DadId'})
// this will add the attribute DadId to Person
 
// In both cases you will be able to do:
Person#setFather
Person#getFather
 
// If you need to join a table twice you can double join the same table
Team
.hasOne(Game, {foreignKey : 'homeTeamId'});
.hasOne(Game, {foreignKey : 'awayTeamId'});
Game
.belongsTo(Team);
 
 
// Since v1.3.0 you can also chain associations:
Project
.hasOne(User)
.hasOne(Deadline)
.hasOne(Attachment)
```
To get the association working the other way around &lpar;so from `User` to `Project`&rpar;&comma; it's necessary to do this&colon;
```js
var User = sequelize.define('User', {/* ... */})
var Project = sequelize.define('Project', {/* ... */})
 
// One-way back associations
Project.belongsTo(User)
 
/*
In this example belongsTo will add an attribute UserId to the Project model!
That's the only difference to hasMany. Self references are working the very same way!
*/
```
## One-To-Many associations
One-To-Many associations are connecting one source with multiple targets&period; The targets however are again connected to exactly one specific source&period;
```js
var User = sequelize.define('User', {/* ... */})
var Project = sequelize.define('Project', {/* ... */})
 
// OK. Now things get more complicated (not really visible to the user :)).
// First let's define a hasMany association
Project.hasMany(User, {as: 'Workers'})
```
This will add the attribute ProjectId or `project_id` to User. Instances of Project will get the accessors getWorkers and setWorkers. We could just leave it the way it is and let it be a one-way association.
But we want more! Let's define it the other way around by creating a many to many assocation in the next section:
## Many-To-Many associations
Many-To-Many associations are used to connect sources with multiple targets&period; Furthermore the targets can also have connections to multiple sources&period;
```js
// again the Project association to User
Project.hasMany(User)
 
// now comes the association between User and Project
User.hasMany(Project)
```
This will remove the attribute `ProjectId` (or `project_id`) from User and create a new model called ProjectsUsers with the equivalent foreign keys `ProjectId`(or `project_id`) and `UserId` (or `user_id`). Whether the attributes are camelcase or not depends on the two models joined by the table (in this case User and Project).
This will add methods `getUsers`, `setUsers`, `addUsers` to `Project`, and `getProjects`, `setProjects` and `addProject` to `User`.
Sometimes you may want to rename your models when using them in associations. Let's define users as workers and projects as tasks by using the alias (`as`) option:
```js
User.hasMany(Project, { as: 'Tasks', through: 'worker_tasks' })
Project.hasMany(User, { as: 'Workers', through: 'worker_tasks' })
```
Notice how we used the `through` option together with the alias in the code above. This is needed to tell sequelize that the two `hasMany` calls are actually two sides of the same association. If you don't use an alias (as shown in the first example of this section) this matching happens
automagically, but with aliassed assocations `through` is required.
Of course you can also define self references with hasMany:
```js
Person.hasMany(Person, { as: 'Children' })
// This will create the table ChildrenPersons which stores the ids of the objects.
 
// You can also reference the same Model without creating a junction
// table (but only if each object will have just one 'parent'). If you need that,
// use the option foreignKey and set through to null
Comment.hasMany(Comment, { as: 'Children', foreignKey: 'ParentId', through: null })
```
By default, sequelize will handle everything related to the join table for you. However, sometimes you might want some more control over the table. This is where th e`through` options comes in handy.
If you just want to control the name of the join table, you can pass a string:
```js
Project.hasMany(User, {through: 'project_has_users'})
User.hasMany(Project, {through: 'project_has_users'})
```
If you want additional attributes in your join table&comma; you can define a model for the join table in sequelize&comma; before you define the association&comma; and then tell sequelize that it should use that model for joining&comma; instead of creating a new one&colon;
```js
User = sequelize.define('User', {})
Project = sequelize.define('Project', {})
UserProjects = sequelize.define('UserProjects', {
status: DataTypes.STRING
})
 
User.hasMany(Project, { through: UserProjects })
Project.hasMany(User, { through: UserProjects })
```
To add a new project to a user and set it's status, you pass an extra object to the setter, which contains the attributes for the join table
```js
user.addProject(project, { status: 'started' })
```
By default the code above will add ProjectId and UserId to the UserProjects table&comma; and_remove any previsouly defined primary key attribute _- the table will be uniquely identified by the combination of the keys of the two tables&comma; and there is no reason to have other PK columns. To enforce a primary key on the `UserProjects` model you can add it manually.
```js
UserProjects = sequelize.define('UserProjects', {
id: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true
},
status: DataTypes.STRING
})
```
## Naming strategy
By default sequelize will use the model name (the name passed to `sequelize.define`) to figure out the name of the model when used in associations. For example, a model named `user` will add the functions `get/set/add User` to instances of the associated model, and a property named `.user` in eager loading, while a model named `User` will add the same functions, but a property named `.User` (notice the upper case U) in eager loading.
As we've already seen, you can alias models in associations using `as`. In single assocations (has one and belongs to), the alias should be singular, while for many associations (has many) it should be plural. Sequelize then uses the [inflection ][0]library to convert the alias to its singular form. However, this might not always work for irregular or non-english words. In this case, you can provide both the plural and the singular form of the alias:
```js
User.hasMany(Project, { as: { singular: 'task', plural: 'tasks' }})
// Notice that inflection has no problem singularizing tasks, this is just for illustrative purposes.
```
If you know that a model will always use the same alias in associations, you can provide it when creating the model
```js
var Project = sequelize.define('project', attributes, {
name: {
singular: 'task',
plural: 'tasks',
}
})
 
User.hasMany(Project);
```
This will add the functions `add/set/get Tasks` to user instances.
## Associating objects
Because Sequelize is doing a lot of magic&comma; you have to call `Sequelize.sync` after setting the associations&excl; Doing so will allow you the following&colon;
```js
Project.hasMany(Task)
Task.hasMany(Project)
 
Project.create()...
Task.create()...
Task.create()...
 
// save them... and then:
project.setTasks([task1, task2]).success(function() {
// saved!
})
 
// ok now they are save... how do I get them later on?
project.getTasks().success(function(associatedTasks) {
// associatedTasks is an array of tasks
})
 
// You can also pass filters to the getter method.
// They are equal to the options you can pass to a usual finder method.
project.getTasks({ where: 'id > 10' }).success(function(tasks) {
// tasks with an id greater than 10 :)
})
 
// You can also only retrieve certain fields of a associated object.
// This example will retrieve the attibutes "title" and "id"
project.getTasks({attributes: ['title']}).success(function(tasks) {
// tasks with an id greater than 10 :)
})
```
To remove created associations you can just call the set method without a specific id&colon;
```js
// remove the association with task1
project.setTasks([task2]).success(function(associatedTasks) {
// you will get task2 only
})
 
// remove 'em all
project.setTasks([]).success(function(associatedTasks) {
// you will get an empty array
})
 
// or remove 'em more directly
project.removeTask(task1).success(function() {
// it's gone
})
 
// and add 'em again
project.addTask(task1).success(function() {
// it's back again
})
```
You can of course also do it vice versa&colon;
```js
// project is associated with task1 and task2
task2.setProject(null).success(function() {
// and it's gone
})
```
For hasOne&sol;belongsTo its basically the same&colon;
```js
Task.hasOne(User, {as: "Author"})
Task#setAuthor(anAuthor)
```
Adding associations to a relation with a custom join table can be done in two ways &lpar;continuing with the associations defined in the previous chapter&rpar;&colon;
```js
// Either by adding a property with the name of the join table model to the object, before creating the association
project.UserProjects = {
status: 'active'
}
u.addProject(project)
 
// Or by providing a second argument when adding the association, containing the data that should go in the join table
u.addProject(project, { status: 'active' })
 
 
// When associating multiple objects, you can combine the two options above. In this case the second argument
// will be treated as a defaults object, that will be used if no data is provided
project1.UserProjects = {
status: 'inactive'
}
 
u.setProjects([project1, project2], { status: 'active' })
// The code above will record inactive for project one, and active for project two in the join table
```
When getting data on an association that has a custom join table&comma; the data from the join table will be returned as a DAO instance&colon;
```js
u.getProjects().success(function(projects) {
var project = projects[0]
 
if (project.UserProjects.status === 'active') {
// .. do magic
 
// since this is a real DAO instance, you can save it directly after you are done doing magic
project.UserProjects.save()
}
})
```
If you only need some of the attributes from the join table&comma; you can provide an array with the attributes you want&colon;
```js
// This will select only name from the Projects table, and only status from the UserProjects table
user.getProjects({ attributes: ['name'], joinTableAttributes: ['status']})
```
## Check associations
You can also check if an object is already associated with another one &lpar;N&colon;M only&rpar;&period; Here is how you'd do it&colon;
```js
// check if an object is one of associated ones:
Project.create({ /* */ }).success(function(project) {
User.create({ /* */ }).success(function(user) {
project.hasUser(user).success(function(result) {
// result would be false
project.addUser(user).success(function() {
project.hasUser(user).success(function(result) {
// result would be true
})
})
})
})
})
 
// check if all associated objects are as expected:
// let's assume we have already a project and two users
project.setUsers([user1, user2]).success(function() {
project.hasUsers([user1]).success(function(result) {
// result would be false
project.hasUsers([user1, user2]).success(function(result) {
// result would be true
})
})
})
```
## Foreign Keys
When you create associations between your models in sequelize, foreign key references with constraints will automatically be created. The setup below:
```js
var Task = this.sequelize.define('Task', { title: Sequelize.STRING })
, User = this.sequelize.define('User', { username: Sequelize.STRING })
 
User.hasMany(Task)
Task.belongsTo(User)
```
Will generate the following SQL:
```sql
CREATE TABLE IF NOT EXISTS `User` (
`id` INTEGER PRIMARY KEY,
`username` VARCHAR(255)
);
CREATE TABLE IF NOT EXISTS `Task` (
`id` INTEGER PRIMARY KEY,
`title` VARCHAR(255),
`user_id` INTEGER REFERENCES `User` (`id`) ON DELETE SET NULL ON UPDATE CASCADE
);
```
The relation between task and user injects the `user_id` foreign key on tasks, and marks it as a reference to the `User` table. By default `user_id` will be set to `NULL` if the referenced user is deleted, and updated if the id of the user id updated. These options can be overriden by passing `onUpdate` and `onDelete` options to the association calls. The validation options are `RESTRICT, CASCADE, NO ACTION, SET DEFAULT, SET NULL`.
For 1:1 and 1:m associations the default option is `SET NULL` for deletion, and `CASCADE` for updates. For n:m, the default for both is `CASCADE`. This means, that if you delete or update a row from one side of an n:m association, all the rows in the join table refrencing that row will also be deleted or updated.
Adding constriants between tables means that tables must be created in the database in a certain order, when using `sequelize.sync`. If Task has a reference to User, the User table must be created before the Task table can be created. This can sometimes lead to circular references, where sequelize cannot find an order in which to sync. Imagine a scenario of documents and versions. A document can have multiple versions, and for convenience, a document has an reference to it's current version.
```js
var Document = this.sequelize.define('Document', {
author: Sequelize.STRING
})
, Version = this.sequelize.define('Version', {
timestamp: Sequelize.DATE
})
Document.hasMany(Version) // This adds document_id to version
Document.belongsTo(Version, { as: 'Current', foreignKey: 'current_version_id'}) // This adds current_version_id to document
```
However, the code above will result in the following error: `Cyclic dependency found. 'Document' is dependent of itself. Dependency Chain: Document -> Version => Document`. In order to alleviate that, we can pass `constraints: false` to one of the associations:
```js
Document.hasMany(Version)
Document.belongsTo(Version, { as: 'Current', foreignKey: 'current_version_id', constraints: false})
```
Which will allow us to sync the tables correctly:
```sql
CREATE TABLE IF NOT EXISTS `Document` (
`id` INTEGER PRIMARY KEY,
`author` VARCHAR(255),
`current_version_id` INTEGER
);
CREATE TABLE IF NOT EXISTS `Version` (
`id` INTEGER PRIMARY KEY,
`timestamp` DATETIME,
`document_id` INTEGER REFERENCES `Document` (`id`) ON DELETE SET NULL ON UPDATE CASCADE
);
```
### Enforcing a foreign key reference without constraints
Some times you may want to reference another table, without adding any constraints, or associations. In that case you can manually add the reference attributes to your schema definition, and mark the relations between them.
```js
var Series, Trainer, Video
 
// Series has a trainer_id=Trainer.id foreign reference key after we call Trainer.hasMany(series)
Series = sequelize.define('Series', {
title: DataTypes.STRING,
sub_title: DataTypes.STRING,
description: DataTypes.TEXT,
 
// Set FK relationship (hasMany) with `Trainer`
trainer_id: {
type: DataTypes.INTEGER,
references: "Trainer",
referencesKey: "id"
}
})
 
Trainer = sequelize.define('Trainer', {
first_name: DataTypes.STRING,
last_name: DataTypes.STRING
});
 
// Video has a series_id=Series.id foreign reference key after we call Series.hasOne(Video)...
Video = sequelize.define('Video', {
title: DataTypes.STRING,
sequence: DataTypes.INTEGER,
description: DataTypes.TEXT,
 
// set relationship (hasOne) with `Series`
series_id: {
type: DataTypes.INTEGER,
references: Series, // Can be both a string representing the table name, or a reference to the model
referencesKey: "id"
}
});
 
Series.hasOne(Video);
Trainer.hasMany(Series);
```
[0]: https://www.npmjs.org/package/inflection
\ No newline at end of file
Hooks (also known as callbacks or lifecycle events), are functions which are called before and after calls in sequelize are executed. For example, if you want to always set a value on a model before saving it, you can add a `beforeUpdate` hook.
## Order of Operations
```
(1)
beforeBulkCreate(daos, fields, fn)
beforeBulkDestroy(daos, fields, fn)
beforeBulkUpdate(daos, fields, fn)
(2)
beforeValidate(dao, fn)
(-)
validate
(3)
afterValidate(dao, fn)
(4)
beforeCreate(dao, fn)
beforeDestroy(dao, fn)
beforeUpdate(dao, fn)
(-)
create
destroy
update
(5)
afterCreate(dao, fn)
afterDestroy(dao, fn)
afterUpdate(dao, fn)
(6)
afterBulkCreate(daos, fields, fn)
afterBulkDestory(daos, fields, fn)
afterBulkUpdate(daos, fields, fn)
```
## Declaring Hooks
There are currently three ways to programmatically add hooks. A hook function always runs asynchronousĺy, and can be resolved either by calling a callback (passed as the last argument),
or by returning a promise.
```js
// Method 1 via the .define() method
var User = sequelize.define('User', {
username: DataTypes.STRING,
mood: {
type: DataTypes.ENUM,
values: ['happy', 'sad', 'neutral']
}
}, {
hooks: {
beforeValidate: function(user, fn) {
user.mood = 'happy'
fn(null, user)
},
afterValidate: function(user, fn) {
user.username = 'Toni'
fn(null, user)
}
}
})
// Method 2 via the .hook() method
var User = sequelize.define('User', {
username: DataTypes.STRING,
mood: {
type: DataTypes.ENUM,
values: ['happy', 'sad', 'neutral']
}
})
User.hook('beforeValidate', function(user, fn) {
user.mood = 'happy'
fn(null, user)
})
User.hook('afterValidate', function(user) {
return sequelize.Promise.reject("I'm afraid I can't let you do that!")
})
// Method 3 via the direct method
var User = sequelize.define('User', {
username: DataTypes.STRING,
mood: {
type: DataTypes.ENUM,
values: ['happy', 'sad', 'neutral']
}
})
User.beforeValidate(function(user) {
user.mood = 'happy'
return sequelize.Promise.resolve(user)
})
User.afterValidate(function(user, fn) {
user.username = 'Toni'
fn(null, user)
})
```
### Instance hooks
The following hooks will emit whenever you're editing a single object...
```
beforeValidate
afterValidate
beforeCreate / beforeUpdate / beforeDestroy
afterCreate / afterUpdate / afterDestroy
```
```js
// ...define ...
User.beforeCreate(function(user, fn) {
if (user.accessLevel > 10 && user.username !== "Boss") {
return fn("You can't grant this user an access level above 10!")
}
return fn()
})
```
This example will emit an error:
```js
User.create({username: 'Not a Boss', accessLevel: 20}).error(function(err) {
console.log(err) // You can't grant this user an access level above 10!
})
```
The following example would emit a success event:
```js
User.create({username: 'Boss', accessLevel: 20}).success(function(user) {
console.log(user) // user object with username as Boss and accessLevel of 20
})
```
### Model hooks
Sometimes you'll be editing more than one record at a time by utilizing the `bulkCreate, update, destroy` methods on the model. The following will emit whenever you're using one of those methods.
```
beforeBulkCreate / beforeBulkUpdate / beforeBulkDestroy
afterBulkCreate / afterBulkUpdate / afterBulkDestroy
```
If you want to emit hooks for each individual record, along with the bulk hooks you can pass `individualHooks: true` to the call.
```js
Model.destroy({accessLevel: 0}, {individualHooks: true})
// Will select all records that are about to be deleted and emit before- + after- Destroy on each instance
Model.update({username: 'Toni'}, {accessLevel: 0}, {individualHooks: true})
// Will select all records that are about to be updated and emit before- + after- Update on each instance
Model.bulkCreate({accessLevel: 0}, null, {individualHooks: true})
// Will select all records that are about to be deleted and emit before- + after- Create on each instance
```
Some model hooks have two or three parameters sent to each hook depending on it's type.
```js
Model.beforeBulkCreate(function(records, fields, fn) {
// records = the first argument sent to .bulkCreate
// fields = the second argument sent to .bulkCreate
})
Model.bulkCreate([
{username: 'Toni'}, // part of records argument
{username: 'Tobi'} // part of records argument
], ['username'] /* part of fields argument */)
Model.beforeBulkUpdate(function(attributes, where, fn) {
// attributes = first argument sent to Model.update
// where = second argument sent to Model.update
})
Model.update({gender: 'Male'} /*attributes argument*/, {username: 'Tom'} /*where argument*/)
Model.beforeBulkDestroy(function(whereClause, fn) {
// whereClause = first argument sent to Model.destroy
})
Model.destroy({username: 'Tom'} /*whereClause argument*/)
```
## Associations
For the most part hooks will work the same for instances when being associated except a few things
1. When using add/set\[s\] functions the beforeUpdate/afterUpdate hooks will run.
2. The only way to call beforeDestroy/afterDestroy hooks are on associations with `onDelete: 'cascade'` and the option `hooks: true`. For instance:
```js
var Projects = sequelize.define('Projects', {
title: DataTypes.STRING
})
var Tasks = sequelize.define('Tasks', {
title: DataTypes.STRING
})
Projects.hasMany(Tasks, {onDelete: 'cascade', hooks: true})
Tasks.belongsTo(Projects)
```
This code will run beforeDestroy/afterDestroy on the Tasks table. Sequelize, by default, will try to optimize your queries as much as possible.
When calling cascade on delete, Sequelize will simply execute a
```sql
DELETE FROM `table` WHERE associatedIdentifiier = associatedIdentifier.primaryKey
```
However, adding `hooks: true` explicitly tells Sequelize that optimization is not of your concern and will perform a `SELECT` on the associated objects and destroy each instance one by one in order to be able to call the hooks with the right parameters.
## A Note About Transactions
Note that many model operations in Sequelize allow you to specify a transaction in the options parameter of the method. If a transaction _is_ specified in the original call, it will be present in the options parameter passed to the hook function. For example, consider the following snippet:
```js
// Here we use the promise-style of async hooks rather than
// the callback.
User.hook('afterCreate', function(user, options) {
// 'trans' will be available in options.transaction
// This operation will be part of the same transaction as the
// original User.create call.
return User.update({
mood: 'sad'
}, {
where: {
id: user.id
},
transaction: options.transaction
});
});
sequelize.transaction(function(trans) {
User.create({
username: 'someguy',
mood: 'happy'
}, {
transaction: trans
});
});
```
If we had not included the transaction option in our call to `User.update` in the preceding code, no change would have occurred, since our newly created user does not exist in the database until the pending transaction has been committed.
### Internal Transactions
It is very important to recognize that sequelize may make use of transactions internally for certain operations such as `Model.findOrCreate`. If your hook functions execute read or write operations that rely on the object's presence in the database, or modify the object's stored values like the example in the preceding section, you should always specify `{ transaction: options.transaction }`.
If the hook has been called in the process of a transacted operation, this makes sure that your dependent read/write is a part of that same transaction. If the hook is not transacted, you have simply specified `{ transaction: null }` and can expect the default behaviour.
\ No newline at end of file
## Installation
You have two options to install Sequelize:
1&period; Install it via NPM:
```bash
# Use npm on the commandline:
$ npm install sequelize
// Then require the installed library in your application code:
var Sequelize = require("sequelize")
```
2&period; Download the code from the git repository and require it's entry file index&period;js&colon;
```bash
# Checkout the current code from the repository using the commandline
$ cd path/to/lib
$ git clone git://github.com/sequelize/sequelize.git
// Then require the installed library in your application code&colon;
var Sequelize = require(__dirname + "/lib/sequelize/index")
```
This will make the class `Sequelize` available.
\ No newline at end of file
## Building a not-persistant instance
In order to create instances of defined classes just do as follows&period; You might recognize the syntax if you coded Ruby in the past&period; Using the `build`-method will return an unsaved object&comma; which you explicitly have to save&period;
```js
var project = Project.build({
title: 'my awesome project',
description: 'woot woot. this will make me a rich man'
})
 
var task = Task.build({
title: 'specify the project idea',
description: 'bla',
deadline: new Date()
})
```
Built instances will automatically get default values when they were defined&colon;
```js
// first define the model
var Task = sequelize.define('Project', {
title: Sequelize.STRING,
rating: { type: Sequelize.STRING, defaultValue: 3 }
})
 
// now instantiate an object
var task = Task.build({title: 'very important task'})
 
task.title // ==> 'very important task'
task.rating // ==> 3
```
To get it stored in the database&comma; use the `save`-method and catch the events ... if needed&colon;
```js
project.save().success(function() {
// my nice callback stuff
})
 
task.save().error(function(error) {
// mhhh, wth!
})
 
// you can also build, save and access the object with chaining:
Task
.build({ title: 'foo', description: 'bar', deadline: new Date() })
.save()
.success(function(anotherTask) {
// you can now access the currently saved task with the variable anotherTask... nice!
}).error(function(error) {
// Ooops, do some error-handling
})
```
## Creating persistant instances
Besides constructing objects&comma; that needs an explicit save call to get stored in the database&comma; there is also the possibility to do all those steps with one single command&period; It's called `create`.
```js
Task.create({ title: 'foo', description: 'bar', deadline: new Date() }).success(function(task) {
// you can now access the newly created task via the variable task
})
```
It is also possible to define which attributes can be set via the create method&period; This can be especially very handy if you create database entries based on a form which can be filled by a user&period; Using that would for example allow you to restrict the `User` model to set only a username and an address but not an admin flag&colon;
```js
User.create({ username: 'barfooz', isAdmin: true }, [ 'username' ]).success(function(user) {
// let's assume the default of isAdmin is false:
console.log(user.values) // => { username: 'barfooz', isAdmin: false }
})
```
## Updating / Saving / Persisting an instance
Now lets change some values and save changes to the database&period;&period;&period; There are two ways to do that&colon;
```js
// way 1
task.title = 'a very different title now'
task.save().success(function() {})
 
// way 2
task.updateAttributes({
title: 'a very different title now'
}).success(function() {})
```
It's also possible to define which attributes should be saved when calling`save`&comma; by passing an array of column names&period; This is useful when you set attributes based on a previously defined object&period; E&period;g&period; if you get the values of an object via a form of a web app&period; Furthermore this is used internally for `updateAttributes`&period; This is how it looks like&colon;
```js
task.title = 'foooo'
task.description = 'baaaaaar'
task.save(['title']).success(function() {
// title will now be 'foooo' but description is the very same as before
})
 
// The equivalent call using updateAttributes looks like this:
task.updateAttributes({ title: 'foooo', description: 'baaaaaar'}, ['title']).success(function() {
// title will now be 'foooo' but description is the very same as before
})
```
## Destroying / Deleting persistant instances
Once you created an object and got a reference to it&comma; you can delete it from the database&period; The relevant method is `destroy`&colon;
```js
Task.create({ title: 'a task' }).success(function(task) {
// now you see me...
 
task.destroy().success(function() {
// now i'm gone :)
})
})
```
If the `paranoid` options is true, the object will not be deleted, instead the `deletedAt` column will be set to the current timestamp. To force the deletion, you can pass `force: true` to the destroy call:
```js
task.destroy({ force: true })
```
## Working in bulk (creating, updating and destroying multiple rows at once)
In addition to updating a single instance, you can also create, update, and delete multiple instances at once. The functions you are looking for are called
* `Model.bulkCreate`
* `Model.update`
* `Model.destroy`
Since you are working with multiple models, the callbacks will not return DAO instances. BulkCreate will return an array of model instances/DAOs, they will however, unlike `create`, not have the resulting values of autoIncrement attributes.`update` and `destroy` will return the number of affected rows.
First lets look at bulkCreate
```js
User.bulkCreate([
{ username: 'barfooz', isAdmin: true },
{ username: 'foo', isAdmin: true },
{ username: 'bar', isAdmin: false }
]).success(function() { // Notice: There are no arguments here, as of right now you'll have to...
User.findAll().success(function(users) {
console.log(users) // ... in order to get the array of user objects
})
})
```
To update several rows at once:
```js
Task.bulkCreate([
{subject: 'programming', status: 'executing'},
{subject: 'reading', status: 'executing'},
{subject: 'programming', status: 'finished'}
]).success(function() {
Task.update(
{status: 'inactive'} /* set attributes' value */,
{subject: 'programming'} /* where criteria */
).success(function(affectedRows) {
// affectedRows will be 2
Task.findAll().success(function(tasks) {
console.log(tasks) // the 'programming' tasks will both have a status of 'inactive'
})
})
})
```
And delete them:
```js
Task.bulkCreate([
{subject: 'programming', status: 'executing'},
{subject: 'reading', status: 'executing'},
{subject: 'programming', status: 'finished'}
]).success(function() {
Task.destroy(
{subject: 'programming'} /* where criteria */,
{truncate: true /* truncate the whole table, ignoring where criteria */} /* options */
).success(function(affectedRows) {
// affectedRows will be 2
Task.findAll().success(function(tasks) {
console.log(tasks) // no programming, just reading :(
})
})
})
```
If you are accepting values directly from the user, it might be beneficial to limit the columns that you want to actually insert.`bulkCreate()`accepts an options object as the second parameter. The object can have a `fields` parameter, &lpar;an array&rpar; to let it know which fields you want to build explicitly
```js
User.bulkCreate([
{ username: 'foo' },
{ username: 'bar', admin: true}
], { fields: ['username'] }).success(function() {
// nope bar, you can't be admin!
})
```
`bulkCreate` was originally made to be a mainstream&sol;fast way of inserting records&comma; however&comma; sometimes you want the luxury of being able to insert multiple rows at once without sacrificing model validations even when you explicitly tell Sequelize which columns to sift through&period; You can do by adding a `validate: true` property to the optons object.
```js
var Tasks = sequelize.define('Task', {
name: {
type: Sequelize.STRING,
validate: {
notNull: { args: true, msg: 'name cannot be null' }
}
},
code: {
type: Sequelize.STRING,
validate: {
len: [3, 10]
}
}
})
 
Tasks.bulkCreate([
{name: 'foo', code: '123'},
{code: '1234'},
{name: 'bar', code: '1'}
], { validate: true }).error(function(errors) {
/* console.log(errors) would look like:
[
{ record:
...
errors:
{ name: 'SequelizeValidationError',
message: 'Validation error',
errors: [Object] } },
{ record:
...
errors:
{ name: 'SequelizeValidationError',
message: 'Validation error',
errors: [Object] } }
]
*/
})
```
## Values of an instance
If you log an instance you will notice&comma; that there is a lot of additional stuff&period; In order to hide such stuff and reduce it to the very interesting information&comma; you can use the`values`-attribute&period; Calling it will return only the values of an instance&period;
```js
Person.create({
name: 'Rambow',
firstname: 'John'
}).success(function(john) {
console.log(john.values)
})
 
// result:
 
// { name: 'Rambow',
// firstname: 'John',
// id: 1,
// createdAt: Tue, 01 May 2012 19:12:16 GMT,
// updatedAt: Tue, 01 May 2012 19:12:16 GMT
// }
```
**Hint&colon;**You can also transform an instance into JSON by using `JSON.stringify(instance)`&period; This will basically return the very same as `values`&period;
## Reloading instances
If you need to get your instance in sync&comma; you can use the method`reload`&period; It will fetch the current data from the database and overwrite the attributes of the model on which the method has been called on&period;
```js
Person.find({ where: { name: 'john' } }).success(function(person) {
person.name = 'jane'
console.log(person.name) // 'jane'
 
person.reload().success(function() {
console.log(person.name) // 'john'
})
})
```
## Incrementing certain values of an instance
In order to increment values of an instance without running into concurrency issues&comma; you may use `increment`&period;
First of all you can define a field and the value you want to add to it&period;
```js
User.find(1).success(function(user) {
user.increment('my-integer-field', 2).success(/* ... */)
})
```
Second&comma; you can define multiple fields and the value you want to add to them&period;
```js
User.find(1).success(function(user) {
user.increment([ 'my-integer-field', 'my-very-other-field' ], 2).success(/* ... */)
})
```
Third&comma; you can define an object containing fields and its increment values&period;
```js
User.find(1).success(function(user) {
user.increment({
'my-integer-field': 2,
'my-very-other-field': 3
}).success(/* ... */)
})
```
## Decrementing certain values of an instance
In order to decrement values of an instance without running into concurrency issues&comma; you may use `decrement`&period;
First of all you can define a field and the value you want to add to it&period;
```js
User.find(1).success(function(user) {
user.decrement('my-integer-field', 2).success(/* ... */)
})
```
Second&comma; you can define multiple fields and the value you want to add to them&period;
```js
User.find(1).success(function(user) {
user.decrement([ 'my-integer-field', 'my-very-other-field' ], 2).success(/* ... */)
})
```
Third&comma; you can define an object containing fields and its decrement values&period;
```js
User.find(1).success(function(user) {
user.decrement({
'my-integer-field': 2,
'my-very-other-field': 3
}).success(/* ... */)
})
```
\ No newline at end of file
Sequelize `2.0.0` introduces a new CLI which is based on [gulp][0] and combines [sequelize-cli][1] and [gulp-sequelize][2]. The CLI ships support for migrations and project bootstrapping. With migrations you can transfer your existing database into another state and vice versa: Those state transitions are saved in migration files, which describe the way how to get to the new state and how to revert the changes in order to get back to the old state.
## The CLI
In order to use the CLI you need to install the respective package:
```bash
$ npm install --save sequelize-cli
```
The CLI currently supports the following commands:
```bash
$ sequelize db:migrate # Run pending migrations.
$ sequelize db:migrate:undo # Revert the last migration run.
$ sequelize help # Display this help text.
$ sequelize init # Initializes the project.
$ sequelize migration:create # Generates a new migration file.
$ sequelize version # Prints the version number.
```
Further and more detailled information about the available commands
can be obtained via the help command:
```bash
$ sequelize help:init
$ sequelize help:db:migrate
$ sequelize help:db:migrate:undo
# etc
```
The latter one for example will print out the following output:
```bash
Sequelize [CLI: v0.0.2, ORM: v1.7.5]
COMMANDS
sequelize db:migrate:undo -- Revert the last migration run.
DESCRIPTION
Revert the last migration run.
OPTIONS
--env The environment to run the command in. Default: development
--options-path The path to a JSON file with additional options. Default: none
--coffee Enables coffee script support. Default: false
--config The path to the config file. Default: config/config.json
```
## Skeleton
The following skeleton shows a typical migration file&period; All migrations are expected to be located in a folder called `migrations` at the very top of the project&period; The sequelize binary can generate a migration skeleton&period; See the aboves section for more details&period;
```js
module.exports = {
up: function(migration, DataTypes, done) {
// logic for transforming into the new state
done() // sets the migration as finished
},
 
down: function(migration, DataTypes, done) {
// logic for reverting the changes
done() // sets the migration as finished
}
}
```
The passed `migration` object can be used to modify the database&period; The `DataTypes` object stores the available data types such as `STRING` or `INTEGER`&period; The third parameter is a callback function which needs to be called once everything was executed&period; The first parameter of the callback function can be used to pass a possible error&period; In that case&comma; the migration will be marked as failed&period; Here is some code&colon;
```js
module.exports = {
up: function(migration, DataTypes, done) {
migration.dropAllTables().complete(done)
 
// equals:
migration.dropAllTables().complete(function(err) {
if (err) {
done(err)
} else {
done(null)
}
})
}
}
```
The available methods of the migration object are the following&period;
## Functions
Using the `migration` object describe before&comma; you will have access to most of already introduced functions&period; Furthermore there are some other methods&comma; which are designed to actually change the database schema&period;
### createTable&lpar;tableName&comma; attributes&comma; options&rpar;
This method allows creation of new tables&period; It is allowed to pass simple or complex attribute definitions&period; You can define the encoding of the table and the table's engine via options
```js
migration.createTable(
'nameOfTheNewTable',
{
id: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true
},
createdAt: {
type: DataTypes.DATE
},
updatedAt: {
type: DataTypes.DATE
},
attr1: DataTypes.STRING,
attr2: DataTypes.INTEGER,
attr3: {
type: DataTypes.BOOLEAN,
defaultValue: false,
allowNull: false
}
},
{
engine: 'MYISAM', // default: 'InnoDB'
charset: 'latin1' // default: null
}
)
```
### dropTable&lpar;tableName&rpar;
This method allows deletion of an existing table&period;
```js
migration.dropTable('nameOfTheExistingTable')
```
### dropAllTables&lpar;&rpar;
This method allows deletion of all existing tables in the database&period;
```js
migration.dropAllTables()
```
### renameTable&lpar;before&comma; after&rpar;
This method allows renaming of an existing table&period;
```js
migration.renameTable('Person', 'User')
```
### showAllTables&lpar;&rpar;
This method returns the name of all existing tables in the database&period;
```js
migration.showAllTables().success(function(tableNames) {})
```
### describeTable&lpar;tableName&rpar;
This method returns an array of hashes containing information about all attributes in the table&period;
```js
migration.describeTable('Person').success(function(attributes) {
/*
attributes will be something like:
 
{
name: {
type: 'VARCHAR(255)', // this will be 'CHARACTER VARYING' for pg!
allowNull: true,
defaultValue: null
},
isBetaMember: {
type: 'TINYINT(1)', // this will be 'BOOLEAN' for pg!
allowNull: false,
defaultValue: false
}
}
*/
})
```
### addColumn&lpar;tableName&comma; attributeName&comma; dataTypeOrOptions&rpar;
This method allows adding columns to an existing table&period; The data type can be simple or complex&period;
```js
migration.addColumn(
'nameOfAnExistingTable',
'nameOfTheNewAttribute',
DataTypes.STRING
)
 
// or
 
migration.addColumn(
'nameOfAnExistingTable',
'nameOfTheNewAttribute',
{
type: DataTypes.STRING,
allowNull: false
}
)
```
### removeColumn&lpar;tableName&comma; attributeName&rpar;
This method allows deletion of a specific column of an existing table&period;
```js
migration.removeColumn('Person', 'signature')
```
### changeColumn&lpar;tableName&comma; attributeName&comma; dataTypeOrOptions&rpar;
This method changes the meta data of an attribute&period; It is possible to change the default value&comma; allowance of null or the data type&period; Please make sure&comma; that you are completely describing the new data type&period; Missing information are expected to be defaults&period;
```js
migration.changeColumn(
'nameOfAnExistingTable',
'nameOfAnExistingAttribute',
DataTypes.STRING
)
 
// or
 
migration.changeColumn(
'nameOfAnExistingTable',
'nameOfAnExistingAttribute',
{
type: DataTypes.FLOAT,
allowNull: false,
default: 0.0
}
)
```
### renameColumn&lpar;tableName&comma; attrNameBefore&comma; attrNameAfter&rpar;
This methods allows renaming attributes&period;
```js
migration.renameColumn('Person', 'signature', 'sig')
```
### addIndex&lpar;tableName&comma; attributes&comma; options&rpar;
This methods creates indexes for specific attributes of a table&period; The index name will be automatically generated if it is not passed via in the options &lpar;see below&rpar;&period;
```js
// This example will create the index person_firstname_lastname
migration.addIndex('Person', ['firstname', 'lastname'])
// This example will create a unique index with the name SuperDuperIndex using the optional 'options' field.
// Possible options:
// - indicesType: UNIQUE|FULLTEXT|SPATIAL
// - indexName: The name of the index. Default is __
// - parser: For FULLTEXT columns set your parser
// - indexType: Set a type for the index, e.g. BTREE. See the documentation of the used dialect
migration.addIndex(
'Person',
['firstname', 'lastname'],
{
indexName: 'SuperDuperIndex',
indicesType: 'UNIQUE'
}
)
```
### removeIndex&lpar;tableName&comma; indexNameOrAttributes&rpar;
This method deletes an existing index of a table&period;
```js
migration.removeIndex('Person', 'SuperDuperIndex')
 
// or
 
migration.removeIndex('Person', ['firstname', 'lastname'])
```
## Programmatic use
If you need to interact with the migrator within your code, you can easily achieve that via `sequelize.getMigrator`. You can specify the path to your migrations as well as a pattern which represents the files that contain the migrations.
```js
var migrator = sequelize.getMigrator({
path: process.cwd() + '/database/migrations',
filesFilter: /\.coffee$/
})
```
Once you have a migrator object, you can run its migration with `migrator.migrate`. By default, this will execute all the up methods within your pending migrations. If you want to rollback a migration, just call it like this:
```js
migrator
.migrate({ method: 'down' })
.success(function() {
// The migrations have been executed!
})
```
[0]: http://gulpjs.com/
[1]: https://github.com/sequelize/cli
[2]: https://github.com/sequelize/gulp-sequelize
\ No newline at end of file
## Utils / Lodash.js
Sequelize comes with some handy utils including references to `lodash` as well as some individual helpers&period; You can access them via `Sequelize.Utils`&period;
You can access all the methods of lodash like this&colon;
```js
Sequelize.Utils._.each(/* ... */)
Sequelize.Utils._.map(/* ... */)
Sequelize.Utils._...
```
Check out the [Lodash][0] page for further information&period;
[0]: http://lodash.com/
## Compatibility
Sequelize is compatible to the following versions of Node.JS:
* 0.8.x
* 0.10.x
## Asynchronicity
Since`v1&period;3&period;0`there are multiple ways of adding listeners to asynchronous requests&period; First of all&comma; each time you call a finder method or save an object&comma; sequelize triggers asynchronous logic&period; To react to the success or the failure &lpar;or both&rpar; of the request&comma; you can do the following&colon;
// the old, pre-v1.3.0 way
Model.findAll().on('success', function(models) { /* foo */ })
Model.findAll().on('failure', function(err) { /* bar */ })
 
// the new, >=v1.3.0 way
// each one is valid
Model.findAll().on('success', function(models) { /* foo */ })
Model.findAll().success(function(models) { /* foo */ })
Model.findAll().ok(function(models) { /* foo */ })
 
// Model.findAll().on('failure', function(err) { /* bar */ }) ==> invalid since v1.5.0
Model.findAll().on('error', function(err) { /* bar */ }) // ==> new since v1.5.0
Model.findAll().error(function(err) { /* bar */ })
Model.findAll().failure(function(err) { /* bar */ })
Model.findAll().fail(function(err) { /* bar */ })
 
Model.findAll().complete(function(err, result) { /* bar */ })
Model.findAll().done(function(err, result) { /* bar */ })
 
// As of 1.7.0 we support Promises/A
var self = User
 
user.find(1).then(function(user1) {
return user1.increment(['aNumber'], 2)
}).then(function(user2) {
return user.find(1)
}).then(function(user3) {
console.log(user3.aNumber) // 2
}, function(err) {
// err...
})
 
 
// For functions with multiple success values (e.g. findOrCreate) there is also spread
 
user.findOrCreate(...).spread(function(user, wasCreated) {
// all arguments are passed
})
user.findOrCreate(...).then(function(user) {
// only the first argument is passed
})
**Please notice&colon;**Since v1&period;5&period;0 the 'error' event is used to notify about errors&period; If such events aren't caught however&comma; Node&period;JS will throw an error&period; So you would probably like to catch them &colon;D
### Additional links
If you want to keep track about latest development of sequelize or to just discuss things with other sequelize users you might want to take a look at the following resources&colon;
* [Twitter&colon; &commat;sdepold][0]
* [Twitter&colon; &commat;sequelizejs][1]
* [ADN&colon; &commat;sdepold][2]
* [IRC&colon; sequelizejs&commat;freenode&period;net][3]
* [XING][4]
* [Facebook][5]
## Companies & Projects
Here is a list of companies and projects that are using Sequelize in real world applications&colon;
### [Shutterstock][6]
Shutterstock Images LLC is a leading global provider of high-quality stock footage&comma; stock photography&comma; vectors and illustrations to creative industry professionals around the world&period; Shutterstock works closely with its growing contributor community of artists&comma; photographers&comma; videographers and illustrators to curate a global marketplace for royalty-free&comma; top-quality imagery&period; Shutterstock adds tens of thousands of rights-cleared images and footage clips each week&comma; with more than 18 million files currently available&period;
### [Clevertech][7]
Clevertech builds web and mobile applications for startups using Lean and Agile methodologies. Clevertech relies on Sequelize for its applications, its speed, versatility and data flexibility. Clevertech contributes back to open source development and its expert developers support the continuing effort to make sequelize the best ORM for Node projects.
### [Metamarkets][8]
Metamarkets enables buyers and sellers of digital media to visualize insights and make decisions with real-time pricing&comma; performance&comma; and audience data&period;
### [filsh][10]
filsh allows you to download online videos from various video
portals like YouTube, Vimeo and Dailymotion in a format you like.
No software required.
### [Using sequelize&quest;][11]
If you want to get listed here&comma; just drop me a line or send me a pull-request on Github&excl;
[0]: http://twitter.com/sdepold
[1]: http://twitter.com/sequelizejs
[2]: https://alpha.app.net/sdepold
[3]: irc://irc.freenode.net/sequelizejs
[4]: https://www.xing.com/net/priec1b5cx/sequelize
[5]: https://www.facebook.com/sequelize
[6]: http://www.shutterstock.com
[7]: http://www.clevertech.biz
[8]: http://metamarkets.com/
[9]: https://innofluence.com
[10]: http://filsh.net
[11]: https://github.com/sequelize/sequelize/tree/gh-pages
\ No newline at end of file
## Definition
To define mappings between a model and a table&comma; use the `define` method&period; Sequelize will then automatically add the attributes `createdAt` and `updatedAt` to it&period; So you will be able to know when the database entry went into the db and when it was updated the last time&period; If you do not want timestamps on your models, only want some timestamps, or you are working with an existing database where the columns are named something else, jump straight on to [configuration ][0]to see how to do that.
```js
var Project = sequelize.define('Project', {
title: Sequelize.STRING,
description: Sequelize.TEXT
})
 
var Task = sequelize.define('Task', {
title: Sequelize.STRING,
description: Sequelize.TEXT,
deadline: Sequelize.DATE
})
```
You can also set some options on each column&colon;
```js
var Foo = sequelize.define('Foo', {
// instantiating will automatically set the flag to true if not set
flag: { type: Sequelize.BOOLEAN, allowNull: false, defaultValue: true},
// default values for dates => current time
myDate: { type: Sequelize.DATE, defaultValue: Sequelize.NOW },
// setting allowNull to false will add NOT NULL to the column, which means an error will be
// thrown from the DB when the query is executed if the column is null. If you want to check that a value
// is not null before querying the DB, look at the validations section below.
title: { type: Sequelize.STRING, allowNull: false},
// Creating two objects with the same value will throw an error. The unique property can be either a
// boolean, or a string. If you provide the same string for multiple columns, they will form a
// composite unique key.
someUnique: {type: Sequelize.STRING, unique: true},
uniqueOne: { type: Sequelize.STRING, unique: 'compositeIndex'},
uniqueTwo: { type: Sequelize.INTEGER, unique: 'compositeIndex'}
// Go on reading for further information about primary keys
identifier: { type: Sequelize.STRING, primaryKey: true},
// autoIncrement can be used to create auto_incrementing integer columns
incrementMe: { type: Sequelize.INTEGER, autoIncrement: true },
// Comments can be specified for each field for MySQL and PG
hasComment: { type: Sequelize.INTEGER, comment: "I'm a comment!" },
// You can specify a custom field name via the "field" attribute:
fieldWithUnderscores: { type: Sequelize.STRING, field: "field_with_underscores" }
})
```
The comment option can also be used on a table&comma; see [model configuration][0]
## Data types
Sequelize currently supports the following datatypes&colon;
```js
Sequelize.STRING // VARCHAR(255)
Sequelize.STRING(1234) // VARCHAR(1234)
Sequelize.STRING.BINARY // VARCHAR BINARY
Sequelize.TEXT // TEXT
 
Sequelize.INTEGER // INTEGER
Sequelize.BIGINT // BIGINT
Sequelize.BIGINT(11) // BIGINT(11)
Sequelize.FLOAT // FLOAT
Sequelize.FLOAT(11) // FLOAT(11)
Sequelize.FLOAT(11, 12) // FLOAT(11,12)
 
Sequelize.DECIMAL // DECIMAL
Sequelize.DECIMAL(10, 2) // DECIMAL(10,2)
 
Sequelize.DATE // DATETIME for mysql / sqlite, TIMESTAMP WITH TIME ZONE for postgres
Sequelize.BOOLEAN // TINYINT(1)
 
Sequelize.ENUM('value 1', 'value 2') // An ENUM with allowed values 'value 1' and 'value 2'
Sequelize.ARRAY(Sequelize.TEXT) // Defines an array. PostgreSQL only.
 
Sequelize.BLOB // BLOB (bytea for PostgreSQL)
Sequelize.BLOB('tiny') // TINYBLOB (bytea for PostgreSQL. Other options are medium and long)
Sequelize.UUID // UUID datatype for PostgreSQL and SQLite, CHAR(36) BINARY for MySQL (use defaultValue: Sequelize.UUIDV1 or Sequelize.UUIDV4 to make sequelize generate the ids automatically)
```
The BLOB data type allows you to insert data both as strings and as buffers&period; When you do a find or findAll on a model which has a BLOB column&comma; that data will always be returned as a buffer&period;
If you are working with the PostgreSQL TIMESTAMP WITHOUT TIME ZONE and you need to parse it to a different timezone&comma; please use the pg library's own parser&colon;
```js
require('pg').types.setTypeParser(1114, function(stringValue) {
return new Date(stringValue + "+0000");
// e.g., UTC offset. Use any offset that you would like.
});
```
In addition to the type mentioned above&comma; integer&comma; bigint and float also support unsigned and zerofill properties&comma; which can be combined in any order&colon;
```js
Sequelize.INTEGER.UNSIGNED // INTEGER UNSIGNED
Sequelize.INTEGER(11).UNSIGNED // INTEGER(11) UNSIGNED
Sequelize.INTEGER(11).ZEROFILL // INTEGER(11) ZEROFILL
Sequelize.INTEGER(11).ZEROFILL.UNSIGNED // INTEGER(11) UNSIGNED ZEROFILL
Sequelize.INTEGER(11).UNSIGNED.ZEROFILL // INTEGER(11) UNSIGNED ZEROFILL
```
_The examples above only show integer&comma; but the same can be done with bigint and float_
Usage in object notation&colon;
```js
// for enums:
sequelize.define('model', {
states: {
type: Sequelize.ENUM,
values: ['active', 'pending', 'deleted']
}
})
```
## Getters & setters
It is possible to define 'object-property' getters and setter functions on your models&comma; these can be used both for 'protecting' properties that map to database fields and for defining 'pseudo' properties&period;
Getters and Setters can be defined in 2 ways &lpar;you can mix and match these 2 approaches&excl;&rpar;&colon;
* as part of a single property definition
* as part of a model options
**N&period;B&period;&colon;**If a getter or setter is defined in both places then the function found in the relevant property definition will always take precedence&period;
### Defining as part of a property
```js
var Foo = sequelize.define('Foo', {
name: { Sequelize.STRING },
title: {
type : Sequelize.STRING,
allowNull: false,
get : function() {
/*
do your magic here and return something!
'this' allows you to access attributes of the model.
 
example: this.getDataValue('name') works
*/
},
set : function(v) { /* do your magic with the input here! */ }
}
});
```
### Defining as part of the model options
Below is an example of defining the getters and setters in the model options&comma; notice the `title_slugslug` getter&comma; it shows how you can define `pseudo` properties on your models&excl; &lpar;the `slugify()` function was taken from the [Underscore&period;String module][1]&comma; it is slightly modified here so that the example remains self-contained&rpar;&comma; note that the `this.title` reference in the `title_slug` getter function will trigger a call to the `title` getter function&period; if you do not want that then use the `getDataValue()` method &lpar;[see below][2]&rpar;&period;
```js
var defaultToWhiteSpace = function(characters) {
if (characters == null)
return '\\s';
else if (characters.source)
return characters.source;
else
return ;
};
 
var slugify = function(str) {
var from = "ąàáäâãåæćęèéëêìíïîłńòóöôõøśùúüûñçżź",
to = "aaaaaaaaceeeeeiiiilnoooooosuuuunczz",
regex = new RegExp('[' + from.replace(/([.*+?^=!:${}()|[\]\/\\])/g, '\\$1') + ']', 'g');
 
if (str == null) return '';
 
str = String(str).toLowerCase().replace(regex, function(c) {
return to.charAt(from.indexOf(c)) || '-';
});
 
return str.replace(/[^\w\s-]/g, '').replace(/([A-Z])/g, '-$1').replace(/[-_\s]+/g, '-').toLowerCase();
}
 
var Foo = sequelize.define('Foo', {
title: {
type : Sequelize.STRING,
allowNull: false,
}
}, {
 
getterMethods : {
title : function() { /* do your magic here and return something! */ },
title_slug : function() { return slugify(this.title); }
},
 
setterMethods : {
title : function(v) { /* do your magic with the input here! */ },
}
});
```
### Helper functions for use inside getter&sol;setter definitions
* retrieving an underlying property value&quest; always use `this.getDataValu()`&comma; e&period;g&colon;
```js
/* a getter for 'title' property */
function() {
return this.getDataValue('title');
}
```
* setting an underlying property value&quest; always use `this.setDataValue()`&comma; e&period;g&period;&colon;
```js
/* a setter for 'title' property */
function(title) {
return this.setDataValue('title', title.toString().toLowerCase());
}
```
**N.B.: **It is important to stick to using the `setDataValue()` and `getDataValue()` functions &lpar;as opposed to accessing the underlying "data values" property directly&rpar; - doing so protects your custom getters and setters from changes in the underlying model implementations &lpar;i&period;e&period; how and where data values are stored in your model instances&rpar;
### Setter methods and Object Initialization
&excl;&excl;&excl;TODO&colon; write about how setters affect object initialization &lpar;both creating new objects with Model&period;build and retrieving existing objects from storage&rpar; &excl;&excl;&excl;&excl;&excl;
## Validations
Model validations, allow you to specify format&sol;content&sol;inheritance validations for each attribute of the model&period; You can perform the validation by calling the `validate()` method on an instance before saving&period; The validations are implemented by [validator][3].
**Note&colon; **In `v1.7.0` validations will now be called when executing the `build()` or `create()` functions.
```js
var ValidateMe = sequelize.define('Foo', {
foo: {
type: Sequelize.STRING,
validate: {
is: ["^[a-z]+$",'i'], // will only allow letters
is: /^[a-z]+$/i, // same as the previous example using real RegExp
not: ["[a-z]",'i'], // will not allow letters
isEmail: true, // checks for email format (foo@bar.com)
isUrl: true, // checks for url format (http://foo.com)
isIP: true, // checks for IPv4 (129.89.23.1) or IPv6 format
isIPv4: true, // checks for IPv4 (129.89.23.1)
isIPv6: true, // checks for IPv6 format
isAlpha: true, // will only allow letters
isAlphanumeric: true // will only allow alphanumeric characters, so "_abc" will fail
isNumeric: true // will only allow numbers
isInt: true, // checks for valid integers
isFloat: true, // checks for valid floating point numbers
isDecimal: true, // checks for any numbers
isLowercase: true, // checks for lowercase
isUppercase: true, // checks for uppercase
notNull: true, // won't allow null
isNull: true, // only allows null
notEmpty: true, // don't allow empty strings
equals: 'specific value', // only allow a specific value
contains: 'foo', // force specific substrings
notIn: [['foo', 'bar']], // check the value is not one of these
isIn: [['foo', 'bar']], // check the value is one of these
notContains: 'bar', // don't allow specific substrings
len: [2,10], // only allow values with length between 2 and 10
isUUID: 4, // only allow uuids
isDate: true, // only allow date strings
isAfter: "2011-11-05", // only allow date strings after a specific date
isBefore: "2011-11-05", // only allow date strings before a specific date
max: 23, // only allow values
min: 23, // only allow values >= 23
isArray: true, // only allow arrays
isCreditCard: true, // check for valid credit card numbers
// custom validations are also possible:
isEven: function(value) {
if(parseInt(value) % 2 != 0) {
throw new Error('Only even values are allowed!')
// we also are in the model's context here, so this.otherField
// would get the value of otherField if it existed
}
}
}
}
})
```
Note that where multiple arguments need to be passed to the built-in validation functions&comma; the arguments to be passed must be in an array&period; But if a single array argument is to be passed&comma; for instance an array of acceptable strings for `isIn`, this will be interpreted as multiple string arguments instead of one array argument&period; To work around this pass a single-length array of arguments&comma; such as `[['one', 'two']]` as shown above&period;
To use a custom error message instead of that provided by node-validator&comma; use an object instead of the plain value or array of arguments&comma; for example a validator which needs no argument can be given a custom message with
```js
isInt: {
msg: "Must be an integer number of pennies"
}
```
or if arguments need to also be passed add an`args`property&colon;
```js
isIn: {
args: [['en', 'zh']],
msg: "Must be English or Chinese"
}
```
When using custom validator functions the error message will be whatever message the thrown`Error`object holds&period;
See [the node-validator project][4]for more details on the built in validation methods&period;
**Hint&colon; **You can also define a custom function for the logging part&period; Just pass a function&period; The first parameter will be the string that is logged&period;
### Validators and`allowNull`
Since `v1.7.0` if a particular field of a model is set to allow null &lpar;with `allowNull: true`&rpar; and that value has been set to `null` &comma; its validators do not run&period; This means you can&comma; for instance&comma; have a string field which validates its length to be at least 5 characters&comma; but which also allows`null`&period;
### Model validations
Since `v1.7.0` &comma; validations can also be defined to check the model after the field-specific validators&period; Using this you could&comma; for example&comma; ensure either neither of `latitude` and `longitude` are set or both&comma; and fail if one but not the other is set&period;
Model validator methods are called with the model object's context and are deemed to fail if they throw an error&comma; otherwise pass&period; This is just the same as with custom field-specific validators&period;
Any error messages collected are put in the validation result object alongside the field validation errors&comma; with keys named after the failed validation method's key in the `validate` option object&period; Even though there can only be one error message for each model validation method at any one time&comma; it is presented as a single string error in an array&comma; to maximize consistency with the field errors&period; &lpar;Note that the structure of `validate()`'s output is scheduled to change in `v2.0`to avoid this awkward situation&period; In the mean time&comma; an error is issued if a field exists with the same name as a custom model validation&period;&rpar;
An example&colon;
```js
var Pub = Sequelize.define('Pub', {
name: { type: Sequelize.STRING },
address: { type: Sequelize.STRING },
latitude: {
type: Sequelize.INTEGER,
allowNull: true,
defaultValue: null,
validate: { min: -90, max: 90 }
},
longitude: {
type: Sequelize.INTEGER,
allowNull: true,
defaultValue: null,
validate: { min: -180, max: 180 }
},
}, {
validate: {
bothCoordsOrNone: function() {
if ((this.latitude === null) === (this.longitude === null)) {
throw new Error('Require either both latitude and longitude or neither')
}
}
}
})
```
In this simple case an object fails validation if either latitude or longitude is given&comma; but not both&period; If we try to build one with an out-of-range latitude and nolongitude, `raging_bullock_arms.validate()` might return
```js
{
'latitude': ['Invalid number: latitude'],
'bothCoordsOrNone': ['Require either both latitude and longitude or neither']
}
```
## Configuration
You can also influence the way Sequelize handles your column names&colon;
```js
var Bar = sequelize.define('Bar', { /* bla */ }, {
// don't add the timestamp attributes (updatedAt, createdAt)
timestamps: false,
 
// don't delete database entries but set the newly added attribute deletedAt
// to the current date (when deletion was done). paranoid will only work if
// timestamps are enabled
paranoid: true,
 
// don't use camelcase for automatically added attributes but underscore style
// so updatedAt will be updated_at
underscored: true,
 
// disable the modification of tablenames; By default, sequelize will automatically
// transform all passed model names (first parameter of define) into plural.
// if you don't want that, set the following
freezeTableName: true,
 
// define the table's name
tableName: 'my_very_custom_table_name'
})
```
If you want sequelize to handle timestamps, but only want some of them, or want your timestamps to be called something else, you can override each column individually:
```js
var Foo = sequelize.define('Foo', { /* bla */ }, {
// don't forget to enable timestamps!
timestamps: true,
 
// I don't want createdAt
createdAt: false,
 
// I want updatedAt to actually be called updateTimestamp
updatedAt: 'updateTimestamp'
 
// And deletedAt to be called destroyTime (remember to enable paranoid for this to work)
deletedAt: 'destroyTime',
paranoid: true
})
```
You can also change the database engine&comma; e&period;g&period; to MyISAM&period; InnoDB is the default.
```js
var Person = sequelize.define('Person', { /* attributes */ }, {
engine: 'MYISAM'
})
 
// or globally
var sequelize = new Sequelize(db, user, pw, {
define: { engine: 'MYISAM' }
})
```
Finaly you can specify a comment for the table in MySQL and PG
```js
var Person = sequelize.define('Person', { /* attributes */ }, {
comment: "I'm a table comment!"
})
```
## Import
You can also store your model definitions in a single file using the `import` method&period; The returned object is exactly the same as defined in the imported file's function&period; Since `v1:5.0` of Sequelize the import is cached&comma; so you won't run into troubles when calling the import of a file twice or more often&period;
```js
// in your server file - e.g. app.js
var Project = sequelize.import(__dirname + "/path/to/models/project")
 
// The model definition is done in /path/to/models/project.js
// As you might notice, the DataTypes are the very same as explained above
module.exports = function(sequelize, DataTypes) {
return sequelize.define("Project", {
name: DataTypes.STRING,
description: DataTypes.TEXT
})
}
```
Since `v1.7.0` the `import` method can now accept a callback as an argument&period;
```js
sequelize.import('Project', function(sequelize, DataTypes) {
return sequelize.define("Project", {
name: DataTypes.STRING,
description: DataTypes.TEXT
})
})
```
## Database synchronization
When starting a new project you won't have a database structure and using Sequelize you won't need to&period; Just specify your model structures and let the library do the rest&period; Currently supported is the creation and deletion of tables&colon;
```js
// Create the tables:
Project.sync() // will emit success or failure event
Task.sync() // will emit success or failure event
 
// Force the creation!
Project.sync({force: true}) // this will drop the table first and re-create it afterwards
 
// drop the tables:
Project.drop() // will emit success or failure event
Task.drop() // will emit success or failure event
 
// event handling:
Project.[sync|drop]().success(function() {
// ok ... everything is nice!
}).error(function(error) {
// oooh, did you entered wrong database credentials?
})
```
Because synchronizing and dropping all of your tables might be a lot of lines to write&comma; you can also let Sequelize do the work for you&colon;
```js
// create all tables... now!
sequelize.sync() // will emit success or failure
 
// force it!
sequelize.sync({force: true}) // emit ... nomnomnom
 
// want to drop 'em all?
sequelize.drop() // I guess you've got it (emit)
 
// emit handling:
sequelize.[sync|drop]().success(function() {
// woot woot
}).error(function(error) {
// whooops
})
```
## Expansion of models
Sequelize allows you to pass custom methods to a model and it's instances&period; Just do the following&colon;
```js
var Foo = sequelize.define('Foo', { /* attributes */}, {
classMethods: {
method1: function(){ return 'smth' }
},
instanceMethods: {
method2: function() { return 'foo' }
}
})
 
// Example:
Foo.method1()
Foo.build().method2()
```
Of course you can also access the instance's data and generate virtual getters&colon;
```js
var User = sequelize.define('User', { firstname: Sequelize.STRING, lastname: Sequelize.STRING }, {
instanceMethods: {
getFullname: function() {
return [this.firstname, this.lastname].join(' ')
}
}
})
 
// Example:
User.build({ firstname: 'foo', lastname: 'bar' }).getFullname() // 'foo bar'
```
You can also set custom methods to all of your models during the instantiation&colon;
```js
var sequelize = new Sequelize('database', 'username', 'password', {
// Other options during the initialization could be here
define: {
classMethods: {
method1: function() {},
method2: function() {}
},
instanceMethods: {
method3: function() {}
}
}
})
 
// Example:
var Foo = sequelize.define('Foo', { /* attributes */});
Foo.method1()
Foo.method2()
Foo.build().method3()
```
## Data retrieval / Finders
Finder methods are designed to get data from the database&period; The returned data isn't just a plain object&comma; but instances of one of the defined classes&period; Check the next major chapter about instances for further information&period; But as those things are instances&comma; you can e&period;g&period; use the just describe expanded instance methods&period; So&comma; here is what you can do&colon;
### find - Search for one specific element in the database
```js
// search for known ids
Project.find(123).success(function(project) {
// project will be an instance of Project and stores the content of the table entry
// with id 123. if such an entry is not defined you will get null
})
 
// search for attributes
Project.find({ where: {title: 'aProject'} }).success(function(project) {
// project will be the first entry of the Projects table with the title 'aProject' || null
})
 
// since v1.3.0: only select some attributes and rename one
Project.find({
where: {title: 'aProject'},
attributes: ['id', ['name', 'title']]
}).success(function(project) {
// project will be the first entry of the Projects table with the title 'aProject' || null
// project.title will contain the name of the project
})
```
### findOrCreate - Search for a specific element or create it if not available
The method `findOrCreate` can be used to check if a certain element is already existing in the database&period; If that is the case the method will result in a respective instance&period; If the element does not yet exist&comma; it will be created.
Let's assume we have an empty database with a `User` model which has a `username` and a `job`.
```js
User
.findOrCreate({ username: 'sdepold' }, { job: 'Technical Lead JavaScript' })
.success(function(user, created) {
console.log(user.values)
console.log(created)
 
/*
{
username: 'sdepold',
job: 'Technical Lead JavaScript',
id: 1,
createdAt: Fri Mar 22 2013 21: 28: 34 GMT + 0100(CET),
updatedAt: Fri Mar 22 2013 21: 28: 34 GMT + 0100(CET)
}
created: true
*/
})
```
The code created a new instance&period; So when we already have an instance &period;&period;&period;
```js
User
.create({ username: 'fnord', job: 'omnomnom' })
.success(function() {
User
.findOrCreate({ username: 'fnord' }, { job: 'something else' })
.success(function(user, created) {
console.log(user.values)
console.log(created)
 
/*
{
username: 'fnord',
job: 'omnomnom',
id: 2,
createdAt: Fri Mar 22 2013 21: 28: 34 GMT + 0100(CET),
updatedAt: Fri Mar 22 2013 21: 28: 34 GMT + 0100(CET)
}
created: false
*/
})
})
```
&period;&period;&period; the existing entry will not be changed&period; See the `job` of the second user&comma; and the fact that created was false&period;
Notice that the success callback has two arguments. When using [promises][5] you should call `spread` [(API ref)][6] instead of `then`, since `then` will only recieve the first argument (the DAO), while `spread` will recieve both the DAO, and the `created` boolean.
### findAndCountAll - Search for multiple elements in the database&comma; returns both data and total count
This is a convienience method that combines`findAll&lpar;&rpar;`and`count&lpar;&rpar;`&lpar;see below&rpar;&comma; this is useful when dealing with queries related to pagination where you want to retrieve data with a`limit`and`offset`but also need to know the total number of records that match the query&period;
The success handler will always receive an object with two properties&colon;
* `count` - an integer&comma; total number records &lpar;matching the where clause&rpar;
* `rows` - an array of objects&comma; the records &lpar;matching the where clause&rpar; within the limit&sol;offset range
```js
Project
.findAndCountAll({
where: ["title LIKE 'foo%'"],
offset: 10,
limit: 2
})
.success(function(result) {
console.log(result.count);
console.log(result.rows);
});
```
The options &lsqb;object&rsqb; that you pass to`findAndCountAll&lpar;&rpar;`is the same as for`findAll&lpar;&rpar;`&lpar;described below&rpar;&period;
### findAll - Search for multiple elements in the database
```js
// find multiple entries
Project.findAll().success(function(projects) {
// projects will be an array of all Project instances
})
 
// also possible:
Project.all().success(function(projects) {
// projects will be an array of all Project instances
})
 
// search for specific attributes - hash usage
Project.findAll({ where: { name: 'A Project' } }).success(function(projects) {
// projects will be an array of Project instances with the specified name
})
 
// search with string replacements
Project.findAll({ where: ["id > ?", 25] }).success(function(projects) {
// projects will be an array of Projects having a greater id than 25
})
 
// search within a specific range
Project.findAll({ where: { id: [1,2,3] } }).success(function(projects) {
// projects will be an array of Projects having the id 1, 2 or 3
// this is actually doing an IN query
})
 
// or
Project.findAll({ where: "name = 'A Project'" }).success(function(projects) {
// the difference between this and the usage of hashes (objects) is, that string usage
// is not sql injection safe. so make sure you know what you are doing!
})
 
// since v1.7.0 we can now improve our where searches
Project.findAll({
where: {
id: {
gt: 6, // id > 6
gte: 6, // id >= 6
lt: 10, // id < 10
lte: 10, // id
ne: 20, // id != 20
between: [6, 10], // BETWEEN 6 AND 10
nbetween: [11, 15] // NOT BETWEEN 11 AND 15
}
}
})
```
### Complex filtering / OR queries
Since `v1.7.0-rc3`, it is possible to do complex where queries with multiple levels of nested AND and OR conditions. In order to do that you can use `Sequelize.or` and `Sequelize.and` and pass an arbitrary amount of arguments to it. Every argument will get transformed into a proper SQL condition and gets joined with the either `AND` or `OR`.
```js
Project.find({
where: Sequelize.and(
{ name: 'a project' },
Sequelize.or(
{ id: [1,2,3] },
{ id: { lt: 10 } }
)
)
})
```
This code will generate the following query:
```sql
SELECT *
FROM `Projects`
WHERE (
`Projects`.`name`='a project'
AND (`Projects`.`id` IN (1,2,3) OR `Projects`.`id` < 10)
)
LIMIT 1
;
```
Notice, that instead of `Sequelize.and` you can also use a plain array which will be treated as `Sequelize.and` if it contains objects or hashes or other complex data types. Furthermore you can use `Sequelize.or` as value for the where clause.
### Manipulating the dataset with limit&comma; offset&comma; order and group
To get more relevant data&comma; you can use limit&comma; offset&comma; order and grouping&colon;
```js
// limit the results of the query
Project.findAll({ limit: 10 })
 
// step over the first 10 elements
Project.findAll({ offset: 10 })
 
// step over the first 10 elements, and take 2
Project.findAll({ offset: 10, limit: 2 })
```
The syntax for grouping and ordering are equal&comma; so below it is only explained with a single example for group&comma; and the rest for order&period; Everything you see below can also be done for group
```js
Project.findAll({order: 'title DESC'})
// yields ORDER BY title DESC
 
Project.findAll({group: 'name'})
// yields GROUP BY name
```
Notice how in the two examples above&comma; the string provided is inserted verbatim into the query&comma; i&period;e&period; column names are not escaped&period; When you provide a string to order &sol; group&comma; this will always be the case as per v 1&period;7&period;0&period; If you want to escape column names&comma; you should provide an array of arguments&comma; even though you only want to order &sol; group by a single column
```js
something.find({
order: [
'name',
// will return `name`
'username DESC',
// will return `username DESC` -- i.e. don't do it!
['username', 'DESC'],
// will return `username` DESC
sequelize.fn('max', sequelize.col('age')),
// will return max(`age`)
[sequelize.fn('max', sequelize.col('age')), 'DESC'],
// will return max(`age`) DESC
[sequelize.fn('otherfunction', sequelize.col('col1'), 12, 'lalala'), 'DESC'],
// will return otherfunction(`col1`, 12, 'lalala') DESC
[sequelize.fn('otherfunction', sequelize.fn('awesomefunction', sequelize.col('col'))), 'DESC']
// will return otherfunction(awesomefunction(`col`)) DESC, This nesting is potentially infinite!
[{ raw: 'otherfunction(awesomefunction(`col`))' }, 'DESC']
// This won't be quoted, but direction will be added
]
})
```
To recap&comma; the elements of the order &sol; group array can be the following&colon;
* String - will be quoted
* Array - first element will be qouted&comma; second will be appended verbatim
* Object -
* Raw will be added verbatim without quoting
* Everything else is ignored&comma; and if raw is not set&comma; the query will fail
* Sequelize&period;fn and Sequelize&period;col returns functions and quoted cools
### Raw queries
Sometimes you might be expecting a massive dataset that you just want to display&comma; without manipulation&period; For each row you select&comma; Sequelize creates a_DAO_&comma; with functions for update&comma; delete&comma; get associations etc&period; If you have thousands of rows&comma; this might take some time&period; If you only need the raw data and don't want to update anything&comma; you can do like this to get the raw data&period;
```js
// Are you expecting a masssive dataset from the DB, and don't want to spend the time building DAOs for each entry?
// You can pass an extra query option to get the raw data instead:
Project.findAll({ where: ... }, { raw: true })
```
### count - Count the occurences of elements in the database
There is also a method for counting database objects&colon;
```js
Project.count().success(function(c) {
console.log("There are " + c + " projects!")
})
 
Project.count({ where: ["id > ?", 25] }).success(function(c) {
console.log("There are " + c + " projects with an id greater than 25.")
})
```
### max - Get the greatest value of a specific attribute within a specific table
And here is a method for getting the max value of an attribute&colon;
```js
/*
Let's assume 3 person objects with an attribute age.
The first one is 10 years old,
the second one is 5 years old,
the third one is 40 years old.
*/
Project.max('age').success(function(max) {
// this will return 40
})
 
Project.max('age', { where: { age: { lt: 20 } } }).success(function(max) {
// will be 10
})
```
### min - Get the least value of a specific attribute within a specific table
And here is a method for getting the min value of an attribute&colon;
```js
/*
Let's assume 3 person objects with an attribute age.
The first one is 10 years old,
the second one is 5 years old,
the third one is 40 years old.
*/
Project.min('age').success(function(min) {
// this will return 5
})
 
Project.min('age', { where: { age: { gt: 5 } } }).success(function(min) {
// will be 10
})
```
### sum - Sum the value of specific attributes
In order to calculate the sum over a specific column of a table, you can
use the `sum` method.
```js
/*
Let's assume 3 person objects with an attribute age.
The first one is 10 years old,
the second one is 5 years old,
the third one is 40 years old.
*/
Project.sum('age').success(function(sum) {
// this will return 55
})
 
Project.sum('age', { where: { age: { gt: 5 } } }).success(function(sum) {
// wil be 50
})
```
## Eager loading
When you are retrieving data from the database there is a fair chance that you also want to get their associations&period; This is possible since`v1&period;6&period;0`and is called eager loading&period; The basic idea behind that&comma; is the use of the attribute`include`when you are calling`find`or`findAll`&period; Lets assume the following setup&colon;
```js
var User = sequelize.define('User', { name: Sequelize.STRING })
, Task = sequelize.define('Task', { name: Sequelize.STRING })
, Tool = sequelize.define('Tool', { name: Sequelize.STRING })
 
Task.belongsTo(User)
User.hasMany(Task)
User.hasMany(Tool, { as: 'Instruments' })
 
sequelize.sync().done(function() {
// this is where we continue ...
})
```
OK&period; So&comma; first of all&comma; let's load all tasks with their associated user&period;
```js
Task.findAll({ include: [ User ] }).success(function(tasks) {
console.log(JSON.stringify(tasks))
 
/*
[{
"name": "A Task",
"id": 1,
"createdAt": "2013-03-20T20:31:40.000Z",
"updatedAt": "2013-03-20T20:31:40.000Z",
"UserId": 1,
"user": {
"name": "John Doe",
"id": 1,
"createdAt": "2013-03-20T20:31:45.000Z",
"updatedAt": "2013-03-20T20:31:45.000Z"
}
}]
*/
})
```
Notice that the accessor of the associated data is the name of the model in camelcase with lowercased first character&period; Also the accessor is singular as the association is one-to-something&period;
Next thing&colon; Loading of data with many-to-something associations&excl;
```js
User.findAll({ include: [ Task ] }).success(function(users) {
console.log(JSON.stringify(users))
 
/*
[{
"name": "John Doe",
"id": 1,
"createdAt": "2013-03-20T20:31:45.000Z",
"updatedAt": "2013-03-20T20:31:45.000Z",
"tasks": [{
"name": "A Task",
"id": 1,
"createdAt": "2013-03-20T20:31:40.000Z",
"updatedAt": "2013-03-20T20:31:40.000Z",
"UserId": 1
}]
}]
*/
})
```
Notice that the accessor is plural&period; This is because the association is many-to-something&period;
If an association is aliased &lpar;using the`as`option&rpar;&comma; you_must_specify this alias when including the model&period; Notice how the user's`Tool`s are aliased as`Instruments`above&period; In order to get that right you have to specify the model you want to load&comma; as well as the alias&colon;
```js
User.findAll({ include: [{ model: Tool, as: 'Instruments' }] }).success(function(users) {
console.log(JSON.stringify(users))
 
/*
[{
"name": "John Doe",
"id": 1,
"createdAt": "2013-03-20T20:31:45.000Z",
"updatedAt": "2013-03-20T20:31:45.000Z",
"instruments": [{
"name": "Toothpick",
"id": 1,
"createdAt": null,
"updatedAt": null,
"UserId": 1
}]
}]
*/
})
```
### Ordering Eager Loaded Associations
In the case of a one-to-many relationship.
```js
Company.findAll({ include: [ Division ], order: [ [ Division, 'name' ] ] });
Company.findAll({ include: [ Division ], order: [ [ Division, 'name', 'DESC' ] ] });
Company.findAll({
include: [ { model: Division, as: 'Div' } ],
order: [ [ { model: Division, as: 'Div' }, 'name' ] ]
});
Company.findAll({
include: [ { model: Division, include: [ Department ] } ],
order: [ [ Division, Department, 'name' ] ]
});
```
In the case of many-to-many joins, you are also able to sort by attributes in the through table.
```js
Company.findAll({
include: [ { model: Division, include: [ Department ] } ],
order: [ [ Division, DepartmentDivision, 'name' ] ]
});
```
### Nested eager loading
```js
User.findAll({
include: [
{model: Tool, as: 'Instruments', include: [
{model: Teacher, include: [ /* etc */]}
]}
]
}).success(function(users) {
console.log(JSON.stringify(users))
 
/*
[{
"name": "John Doe",
"id": 1,
"createdAt": "2013-03-20T20:31:45.000Z",
"updatedAt": "2013-03-20T20:31:45.000Z",
"instruments": [{ // 1:M and N:M association
"name": "Toothpick",
"id": 1,
"createdAt": null,
"updatedAt": null,
"UserId": 1,
"Teacher": { // 1:1 association
"name": "Jimi Hendrix"
}
}]
}]
*/
})
```
**Final note&colon;**If you include an object which is not associated&comma; Sequelize will throw an error&period;
```js
Tool.findAll({ include: [ User ] }).success(function(tools) {
console.log(JSON.stringify(tools))
})
 
// Error: User is not associated to Tool!
```
[0]: #configuration
[1]: https://github.com/epeli/underscore.string
[2]: #get_and_set_helper_funcs
[3]: https://github.com/chriso/validator.js
[4]: https://github.com/chriso/node-validator
[5]: /docs/latest/misc#asynchronicity
[6]: https://github.com/petkaantonov/bluebird/blob/master/API.md#spreadfunction-fulfilledhandler--function-rejectedhandler----promise
\ No newline at end of file
TODO - something about how promises work
\ No newline at end of file
## Transactions
```js
sequelize.transaction(function(t) {
// we just opened a new connection to the database which is transaction exclusive.
// also we send some first transaction queries to the database.
// do some async stuff ...
// if everything is ok ... commit the transaction
t.commit().success(function() {})
// if something failed ... rollback the transaction
t.rollback().success(function() {})
// the commit / rollback will emit events which can be observed via:
t.done(function() {
/* we will be here once the transaction
has been committed / reverted */
})
})
sequelize.transaction(function(t) {
User.create({ username: 'foo' }, { transaction: t }).success(function() {
// this user will only be available inside the session
User.all({ transaction: t }) // will return the user
User.all() // will not return the user
})
})
```
\ No newline at end of file
## Basic usage
To get the ball rollin' you first have to create an instance of Sequelize&period; Use it the following way&colon;
```js
var sequelize = new Sequelize('database', 'username'[, 'password'])
```
This will save the passed database credentials and provide all further methods&period; Furthermore you can specify a non-default host&sol;port&colon;
```js
var sequelize = new Sequelize('database', 'username', 'password', {
host: "my.server.tld",
port: 12345
})
```
If you just don't have a password&colon;
```js
var sequelize = new Sequelize('database', 'username')
// or
var sequelize = new Sequelize('database', 'username', null)
```
You can also use a connection string&colon;
```js
var sequelize = new Sequelize('mysql://user:pass@example.com:9821/dbname', {
// Look to the next section for possible options
})
```
## Options
Besides the host and the port&comma; Sequelize comes with a whole bunch of options&period; Here they are&colon;
```js
var sequelize = new Sequelize('database', 'username', 'password', {
// custom host; default: localhost
host: 'my.server.tld',
 
// custom port; default: 3306
port: 12345,
 
// custom protocol
// - default: 'tcp'
// - added in: v1.5.0
// - postgres only, useful for heroku
protocol: null,
 
// disable logging; default: console.log
logging: false,
 
// max concurrent database requests; default: 50
maxConcurrentQueries: 100,
 
// the sql dialect of the database
// - default is 'mysql'
// - currently supported: 'mysql', 'sqlite', 'postgres', 'mariadb'
dialect: 'mysql',
 
// you can also pass any dialect options to the underlying dialect library
// - default is empty
// - currently supported: 'mysql', 'mariadb'
dialectOptions: {
socketPath: '/Applications/MAMP/tmp/mysql/mysql.sock',
supportBigNumbers: true,
bigNumberStrings: true
},
 
// the storage engine for sqlite
// - default ':memory:'
storage: 'path/to/database.sqlite',
 
// disable inserting undefined values as NULL
// - default: false
omitNull: true,
 
// a flag for using a native library or not.
// in the case of 'pg' -- set this to true will allow SSL support
// - default: false
native: true,
 
// Specify options, which are used when sequelize.define is called.
// The following example:
// define: {timestamps: false}
// is basically the same as:
// sequelize.define(name, attributes, { timestamps: false })
// so defining the timestamps for each model will be not necessary
// Below you can see the possible keys for settings. All of them are explained on this page
define: {
underscored: false
freezeTableName: false,
syncOnAssociation: true,
charset: 'utf8',
collate: 'utf8_general_ci',
classMethods: {method1: function() {}},
instanceMethods: {method2: function() {}},
timestamps: true
},
 
// similiar for sync: you can define this to always force sync for models
sync: { force: true },
 
// sync after each association (see below). If set to false, you need to sync manually after setting all associations. Default: true
syncOnAssociation: true,
 
// use pooling in order to reduce db connection overload and to increase speed
// currently only for mysql and postgresql (since v1.5.0)
pool: { maxConnections: 5, maxIdleTime: 30},
 
// language is used to determine how to translate words into singular or plural form based on the [lingo project](https://github.com/visionmedia/lingo)
// options are: en [default], es
language: 'en'
})
```
**Hint&colon;** You can also define a custom function for the logging part&period; Just pass a function&period; The first parameter will be the string that is logged&period;
## Read replication
Sequelize supports read replication&comma; i&period;e&period; having multiple servers that you can connect to when you want to do a SELECT query&period; When you do read replication&comma; you specify one or more servers to act as read replicas&comma; and one server to act as the write master&comma; which handles all writes and updates and propagates them to the replicas &lpar;note that the actual replication process is**not **handled by Sequelize&comma; but should be set up in MySql&rpar;&period;
```js
var sequelize = new Sequelize('database', null, null, {
dialect: 'mysql',
port: 3306
replication: {
read: [
{ host: '8.8.8.8', username: 'anotherusernamethanroot', password: 'lolcats!' },
{ host: 'localhost', username: 'root', password: null }
],
write: { host: 'localhost', username: 'root', password: null }
},
pool: { // If you want to override the options used for the read pool you can do so here
maxConnections: 20,
maxIdleTime: 30000
},
})
```
If you have any general settings that apply to all replicas you do not need to provide them for each instance&period; In the code above&comma; database name and port is propagated to all replicas&period; The same will happen for user and password&comma; if you leave them out for any of the replicas&period; Each replica has the following options&colon;`host`&comma;`port`&comma;`username`&comma;`password`&comma;`database`
Sequelize uses a pool to manage connections to your replicas&period; The default options are&colon;
```js
{
maxConnections: 10,
minConnections: 0,
maxIdleTime: 1000
}
```
If you want to modify these&comma; you can pass pool as an options when instantiating Sequelize&comma; as shown above&period;
**Note&colon;** Read replication only works for MySQL at the moment&excl;
## Dialects
With the release of Sequelize`v1&period;6&period;0`&comma; the library got independent from specific dialects&period; This means&comma; that you'll have to add the respective connector library to your project yourself. Version 1.7.0 stable has been released in bundles with the connector libraries (sequelize-mysql, sequelize-postgres etc.) but these bundles are not maintained, and will not be released for 2.0.0 upwards.
### MySQL
In order to get Sequelize working nicely together with MySQL&comma; you'll need to install`mysql&commat;~2&period;0&period;0-alpha7`or higher&period; Once that's done you can use it like this&colon;
```js
var sequelize = new Sequelize('database', 'username', 'password', {
// mysql is the default dialect, but you know...
// for demo purporses we are defining it nevertheless :)
// so: we want mysql!
dialect: 'mysql'
})
```
**Note:** You can pass options directly to dialect library by setting the
`dialectOptions` parameter. See [Options][0]
for examples (currently only mysql and mariadb are supported).
### MariaDB
For MariaDB compatibility you have to install the package `mariasql@0.1.20`, or higher.
The configuration needs to look like this:
```js
var sequelize = new Sequelize('database', 'username', 'password', {
dialect: 'mariadb'
})
```
### SQLite
For SQLite compatibility you'll need`sqlite3&commat;~2&period;1&period;5`&period; Configure Sequelize like this&colon;
```js
var sequelize = new Sequelize('database', 'username', 'password', {
// sqlite! now!
dialect: 'sqlite',
 
// the storage engine for sqlite
// - default ':memory:'
storage: 'path/to/database.sqlite'
})
```
### PostgreSQL
The library for PostgreSQL is`pg&commat;~2&period;0&period;0`&period; You'll just need to define the dialect&colon;
```js
var sequelize = new Sequelize('database', 'username', 'password', {
// gimme postgres, please!
dialect: 'postgres'
})
```
## Executing raw SQL queries
As there are often use cases in which it is just easier to execute raw &sol; already prepared SQL queries&comma; you can utilize the function`sequelize&period;query`&period;
Here is how it works&colon;
```js
// Arguments for raw queries
sequelize.query('your query', [, callee], [, options], [, replacements])
// Quick example
sequelize.query("SELECT * FROM myTable").success(function(myTableRows) {
console.log(myTableRows)
})
// Callee is the model definition. This allows you to easily map a query
// to a predefined model for sequelizejs e.g:
sequelize
.query('SELECT * FROM projects', Projects)
.success(function(projects){
// Each record will now be mapped to the project's DAO-Factory.
console.log(projects)
})
// Options is an object with the following keys:
sequelize
.query('SELECT 1', null, {
// A function (or false) for logging your queries
// Will get called for every SQL query that gets send
// to the server.
logging: console.log,
// If plain is true, then sequelize will only return the first
// record of the result set. In case of false it will all records.
plain: false,
// Set this to true if you don't have a model definition for your query.
raw: false
})
// Note the second argument being null!
// Even if we declared a callee here, the raw: true would
// supersede and return a raw object.
sequelize
.query('SELECT * FROM projects', null, { raw: true })
.success(function(projects) {
console.log(projects)
})
```
Replacements in a query can be done in two different ways, either using
named parameters (starting with `:`), or unnamed, represented by a ?
The syntax used depends on the fourth argument passed to the function:
* If an array is passed, `?` will be replaced in the order that they appear in the array
* If an object is passed, `:key` will be replaced with the keys from that object.
If the object contains keys not found in the query or vice verca, an exception
will be thrown.
```js
sequelize
.query(
'SELECT * FROM projects WHERE status = ?', null,
{ raw: true }, ['active']
)
.success(function(projects) {
console.log(projects)
})
sequelize
.query(
'SELECT * FROM projects WHERE status = :status ', null,
{ raw: true }, { status: 'active' }
)
.success(function(projects) {
console.log(projects)
})
```
**One note:** If the attribute names of the table contain dots, the resulting objects will be nested:
```js
sequelize.query('select 1 as `foo.bar.baz`').success(function(rows) {
console.log(JSON.stringify(rows))
/*
[{
"foo": {
"bar": {
"baz": 1
}
}
}]
*/
})
```
[0]: /docs/latest/usage#options
\ No newline at end of file
No preview for this file type
# Imprint - Boring legal stuff for the rest of us.
As there are people who are suing for fun and glory, you can find the respective information about the author of the page right here. Have fun reading ...
## AUTHOR(S)
```
Main author:
Sascha Depold
Uhlandstr. 122
10717 Berlin
sascha [at] depold [dot] com
```
## INHALTLICHE VERANTWORTUNG
```
Ich übernehme keine Haftung für ausgehende Links.
Daher musst du dich bei Problemen an deren Betreiber wenden!
```
\ No newline at end of file
The Sequelize library provides easy access to MySQL, MariaDB, SQLite or PostgreSQL databases by mapping database entries to objects and vice versa. To put it in a nutshell, it's an ORM (Object-Relational-Mapper). The library is written entirely in JavaScript and can be used in the Node.JS environment.
## Easy installation
```bash
$ npm install sequelize
$ npm install mysql
```
## Simple usage
```js
var Sequelize = require('sequelize')
, sequelize = new Sequelize('database', 'username', 'password')
var User = sequelize.define('User', {
username: Sequelize.STRING,
birthday: Sequelize.DATE
})
sequelize.sync().success(function() {
User.create({
username: 'sdepold',
birthday: new Date(1986, 06, 28)
}).success(function(sdepold) {
console.log(sdepold.values)
})
})
```
## Trusted and used by
[![](/images/shutterstock.png)](docs/misc#shutterstock)
[![](/images/clevertech.png)](docs/misc#clevertech)
[![](/images/metamarkets.png)](docs/misc#metamarkets)
[![](/images/filsh.png)](docs/misc#filsh)
(c) Sascha Depold, [et al.](https://github.com/sequelize/sequelize-doc/graphs/contributors) 2006 - 2014 [Imprint](imprint)
\ No newline at end of file
<!DOCTYPE html>
<!--[if IE 8]><html class="no-js lt-ie9" lang="en" > <![endif]-->
<!--[if gt IE 8]><!--> <html class="no-js" lang="en" > <!--<![endif]-->
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
{% block htmltitle %}
<title>{{ page_title }}</title>
{% endblock %}
{# CSS #}
<link href='https://fonts.googleapis.com/css?family=Lato:400,700|Roboto+Slab:400,700|Inconsolata:400,700' rel='stylesheet' type='text/css'>
<link rel="stylesheet" href="{{ base_url }}/css/theme.css" type="text/css" />
{%- for path in extra_css %}
<link href="{{ path }}" rel="stylesheet">
{%- endfor %}
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/modernizr/2.8.3/modernizr.min.js"></script>
<script src="{{ base_url }}/js/theme.js"></script>
{%- for path in extra_javascript %}
<script src="{{ path }}"></script>
{%- endfor %}
<style>
body {font-size: 90%;}
pre, code {font-size: 100%;}
h3, h4, h5, h6 {color: #2980b9; font-weight: 300}
</style>
{%- block extrahead %} {% endblock %}
</head>
<body class="wy-body-for-nav" role="document">
<div class="wy-grid-for-nav">
{# SIDE NAV, TOGGLES ON MOBILE #}
<nav data-toggle="wy-nav-shift" class="wy-nav-side stickynav">
<div class="wy-side-nav-search">
<a href="{{ homepage_url }}" class="icon icon-home"> {{ site_name }}</a>
{% include "searchbox.html" %}
</div>
<div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="main navigation">
{% include "toc.html" %}
</div>
&nbsp;
</nav>
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap">
{# MOBILE NAV, TRIGGLES SIDE NAV ON TOGGLE #}
<nav class="wy-nav-top" role="navigation" aria-label="top navigation">
<i data-toggle="wy-nav-top" class="icon icon-reorder"></i>
<a href="{{ homepage_url }}">{{ project }}</a>
</nav>
{# PAGE CONTENT #}
<div class="wy-nav-content">
<div class="rst-content">
{% include "breadcrumbs.html" %}
<div role="main">
<div class="section">
{{ content }}
</div>
</div>
{%- block footer %}
{% include "footer.html" %}
{% endblock %}
</div>
</div>
</section>
</div>
<div class="rst-versions" role="note" style="cursor: pointer">
<span class="rst-current-version" data-toggle="rst-current-version">
{% if repo_name == 'GitHub' %}
<a class="icon icon-github" style="float: left; color: #fcfcfc"> GitHub</a>
{% elif repo_name == 'Bitbucket' %}
<a class="icon icon-bitbucket" style="float: left; color: #fcfcfc"> BitBucket</a>
{% endif %}
<span><a href="" style="color: #fcfcfc;">&laquo; Previous</a></span>
<span style="margin-left: 15px"><a href="" style="color: #fcfcfc">Next &raquo;</a></span>
</span>
</div>
</body>
</html>
<div role="navigation" aria-label="breadcrumbs navigation">
<ul class="wy-breadcrumbs">
<li><a href="{{ homepage_url }}">Docs</a> &raquo;</li>
<li>{{ current_page.title }}</li>
<li class="wy-breadcrumbs-aside">
{% if repo_url %}
{% if repo_name == 'GitHub' %}
<a href="{{ repo_url }}" class="icon icon-github"> Edit on GitHub</a>
{% elif repo_name == 'Bitbucket' %}
<a href="{{ repo_url }}" class="icon icon-bitbucket"> Edit on BitBucket</a>
{% endif %}
{% endif %}
</li>
</ul>
<hr/>
</div>
*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block}audio,canvas,video{display:inline-block;*display:inline;*zoom:1}audio:not([controls]){display:none}[hidden]{display:none}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}a:hover,a:active{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:bold}blockquote{margin:0}dfn{font-style:italic}hr{display:block;height:1px;border:0;border-top:1px solid #ccc;margin:20px 0;padding:0}ins{background:#ff9;color:#000;text-decoration:none}mark{background:#ff0;color:#000;font-style:italic;font-weight:bold}pre,.rst-content tt,kbd,samp{font-family:monospace,serif;_font-family:"courier new",monospace;font-size:1em}pre{white-space:pre}q{quotes:none}q:before,q:after{content:"";content:none}small{font-size:85%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-0.5em}sub{bottom:-0.25em}ul,ol,dl{margin:0;padding:0;list-style:none;list-style-image:none}li{list-style:none}dd{margin:0}img{border:0;-ms-interpolation-mode:bicubic;vertical-align:middle;max-width:100%}svg:not(:root){overflow:hidden}figure{margin:0}form{margin:0}fieldset{border:0;margin:0;padding:0}label{cursor:pointer}legend{border:0;*margin-left:-7px;padding:0;white-space:normal}button,input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}button,input{line-height:normal}button,input[type="button"],input[type="reset"],input[type="submit"]{cursor:pointer;-webkit-appearance:button;*overflow:visible}button[disabled],input[disabled]{cursor:default}input[type="checkbox"],input[type="radio"]{box-sizing:border-box;padding:0;*width:13px;*height:13px}input[type="search"]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}input[type="search"]::-webkit-search-decoration,input[type="search"]::-webkit-search-cancel-button{-webkit-appearance:none}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}textarea{overflow:auto;vertical-align:top;resize:vertical}table{border-collapse:collapse;border-spacing:0}td{vertical-align:top}.chromeframe{margin:0.2em 0;background:#ccc;color:#000;padding:0.2em 0}.ir{display:block;border:0;text-indent:-999em;overflow:hidden;background-color:transparent;background-repeat:no-repeat;text-align:left;direction:ltr;*line-height:0}.ir br{display:none}.hidden{display:none !important;visibility:hidden}.visuallyhidden{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.visuallyhidden.focusable:active,.visuallyhidden.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.invisible{visibility:hidden}.relative{position:relative}big,small{font-size:100%}@media print{html,body,section{background:none !important}*{box-shadow:none !important;text-shadow:none !important;filter:none !important;-ms-filter:none !important}a,a:visited{text-decoration:underline}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h2,h3{page-break-after:avoid}}.font-smooth,.icon:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-tag-input-group .wy-tag .wy-tag-remove:before,.rst-content .admonition-title:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content dl dt .headerlink:before,.wy-alert,.rst-content .note,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .tip,.rst-content .warning,.rst-content .seealso,.btn,input[type="text"],input[type="password"],input[type="email"],input[type="url"],input[type="date"],input[type="month"],input[type="time"],input[type="datetime"],input[type="datetime-local"],input[type="week"],input[type="number"],input[type="search"],input[type="tel"],input[type="color"],select,textarea,.wy-tag-input-group,.wy-menu-vertical li.on a,.wy-menu-vertical li.current>a,.wy-side-nav-search>a,.wy-side-nav-search .wy-dropdown>a,.wy-nav-top a{-webkit-font-smoothing:antialiased}.clearfix{*zoom:1}.clearfix:before,.clearfix:after{display:table;content:""}.clearfix:after{clear:both}@font-face{font-family:fontawesome-webfont;font-weight:normal;font-style:normal;src:url("../font/fontawesome_webfont.eot");src:url("../font/fontawesome_webfont.eot?#iefix") format("embedded-opentype"),url("../font/fontawesome_webfont.woff") format("woff"),url("../font/fontawesome_webfont.ttf") format("truetype"),url("../font/fontawesome_webfont.svg#fontawesome-webfont") format("svg")}.icon:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-tag-input-group .wy-tag .wy-tag-remove:before,.rst-content .admonition-title:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content dl dt .headerlink:before{display:inline-block;font-family:fontawesome-webfont;font-style:normal;font-weight:normal;line-height:1;text-decoration:inherit}a .icon,a .wy-inline-validate.wy-inline-validate-success .wy-input-context,.wy-inline-validate.wy-inline-validate-success a .wy-input-context,a .wy-inline-validate.wy-inline-validate-danger .wy-input-context,.wy-inline-validate.wy-inline-validate-danger a .wy-input-context,a .wy-inline-validate.wy-inline-validate-warning .wy-input-context,.wy-inline-validate.wy-inline-validate-warning a .wy-input-context,a .wy-inline-validate.wy-inline-validate-info .wy-input-context,.wy-inline-validate.wy-inline-validate-info a .wy-input-context,a .wy-tag-input-group .wy-tag .wy-tag-remove,.wy-tag-input-group .wy-tag a .wy-tag-remove,a .rst-content .admonition-title,.rst-content a .admonition-title,a .rst-content h1 .headerlink,.rst-content h1 a .headerlink,a .rst-content h2 .headerlink,.rst-content h2 a .headerlink,a .rst-content h3 .headerlink,.rst-content h3 a .headerlink,a .rst-content h4 .headerlink,.rst-content h4 a .headerlink,a .rst-content h5 .headerlink,.rst-content h5 a .headerlink,a .rst-content h6 .headerlink,.rst-content h6 a .headerlink,a .rst-content dl dt .headerlink,.rst-content dl dt a .headerlink{display:inline-block;text-decoration:inherit}.icon-large:before{vertical-align:-10%;font-size:1.33333em}.btn .icon,.btn .wy-inline-validate.wy-inline-validate-success .wy-input-context,.wy-inline-validate.wy-inline-validate-success .btn .wy-input-context,.btn .wy-inline-validate.wy-inline-validate-danger .wy-input-context,.wy-inline-validate.wy-inline-validate-danger .btn .wy-input-context,.btn .wy-inline-validate.wy-inline-validate-warning .wy-input-context,.wy-inline-validate.wy-inline-validate-warning .btn .wy-input-context,.btn .wy-inline-validate.wy-inline-validate-info .wy-input-context,.wy-inline-validate.wy-inline-validate-info .btn .wy-input-context,.btn .wy-tag-input-group .wy-tag .wy-tag-remove,.wy-tag-input-group .wy-tag .btn .wy-tag-remove,.btn .rst-content .admonition-title,.rst-content .btn .admonition-title,.btn .rst-content h1 .headerlink,.rst-content h1 .btn .headerlink,.btn .rst-content h2 .headerlink,.rst-content h2 .btn .headerlink,.btn .rst-content h3 .headerlink,.rst-content h3 .btn .headerlink,.btn .rst-content h4 .headerlink,.rst-content h4 .btn .headerlink,.btn .rst-content h5 .headerlink,.rst-content h5 .btn .headerlink,.btn .rst-content h6 .headerlink,.rst-content h6 .btn .headerlink,.btn .rst-content dl dt .headerlink,.rst-content dl dt .btn .headerlink,.nav .icon,.nav .wy-inline-validate.wy-inline-validate-success .wy-input-context,.wy-inline-validate.wy-inline-validate-success .nav .wy-input-context,.nav .wy-inline-validate.wy-inline-validate-danger .wy-input-context,.wy-inline-validate.wy-inline-validate-danger .nav .wy-input-context,.nav .wy-inline-validate.wy-inline-validate-warning .wy-input-context,.wy-inline-validate.wy-inline-validate-warning .nav .wy-input-context,.nav .wy-inline-validate.wy-inline-validate-info .wy-input-context,.wy-inline-validate.wy-inline-validate-info .nav .wy-input-context,.nav .wy-tag-input-group .wy-tag .wy-tag-remove,.wy-tag-input-group .wy-tag .nav .wy-tag-remove,.nav .rst-content .admonition-title,.rst-content .nav .admonition-title,.nav .rst-content h1 .headerlink,.rst-content h1 .nav .headerlink,.nav .rst-content h2 .headerlink,.rst-content h2 .nav .headerlink,.nav .rst-content h3 .headerlink,.rst-content h3 .nav .headerlink,.nav .rst-content h4 .headerlink,.rst-content h4 .nav .headerlink,.nav .rst-content h5 .headerlink,.rst-content h5 .nav .headerlink,.nav .rst-content h6 .headerlink,.rst-content h6 .nav .headerlink,.nav .rst-content dl dt .headerlink,.rst-content dl dt .nav .headerlink{display:inline}.btn .icon.icon-large,.btn .wy-inline-validate.wy-inline-validate-success .icon-large.wy-input-context,.wy-inline-validate.wy-inline-validate-success .btn .icon-large.wy-input-context,.btn .wy-inline-validate.wy-inline-validate-danger .icon-large.wy-input-context,.wy-inline-validate.wy-inline-validate-danger .btn .icon-large.wy-input-context,.btn .wy-inline-validate.wy-inline-validate-warning .icon-large.wy-input-context,.wy-inline-validate.wy-inline-validate-warning .btn .icon-large.wy-input-context,.btn .wy-inline-validate.wy-inline-validate-info .icon-large.wy-input-context,.wy-inline-validate.wy-inline-validate-info .btn .icon-large.wy-input-context,.btn .wy-tag-input-group .wy-tag .icon-large.wy-tag-remove,.wy-tag-input-group .wy-tag .btn .icon-large.wy-tag-remove,.btn .rst-content .icon-large.admonition-title,.rst-content .btn .icon-large.admonition-title,.btn .rst-content h1 .icon-large.headerlink,.rst-content h1 .btn .icon-large.headerlink,.btn .rst-content h2 .icon-large.headerlink,.rst-content h2 .btn .icon-large.headerlink,.btn .rst-content h3 .icon-large.headerlink,.rst-content h3 .btn .icon-large.headerlink,.btn .rst-content h4 .icon-large.headerlink,.rst-content h4 .btn .icon-large.headerlink,.btn .rst-content h5 .icon-large.headerlink,.rst-content h5 .btn .icon-large.headerlink,.btn .rst-content h6 .icon-large.headerlink,.rst-content h6 .btn .icon-large.headerlink,.btn .rst-content dl dt .icon-large.headerlink,.rst-content dl dt .btn .icon-large.headerlink,.nav .icon.icon-large,.nav .wy-inline-validate.wy-inline-validate-success .icon-large.wy-input-context,.wy-inline-validate.wy-inline-validate-success .nav .icon-large.wy-input-context,.nav .wy-inline-validate.wy-inline-validate-danger .icon-large.wy-input-context,.wy-inline-validate.wy-inline-validate-danger .nav .icon-large.wy-input-context,.nav .wy-inline-validate.wy-inline-validate-warning .icon-large.wy-input-context,.wy-inline-validate.wy-inline-validate-warning .nav .icon-large.wy-input-context,.nav .wy-inline-validate.wy-inline-validate-info .icon-large.wy-input-context,.wy-inline-validate.wy-inline-validate-info .nav .icon-large.wy-input-context,.nav .wy-tag-input-group .wy-tag .icon-large.wy-tag-remove,.wy-tag-input-group .wy-tag .nav .icon-large.wy-tag-remove,.nav .rst-content .icon-large.admonition-title,.rst-content .nav .icon-large.admonition-title,.nav .rst-content h1 .icon-large.headerlink,.rst-content h1 .nav .icon-large.headerlink,.nav .rst-content h2 .icon-large.headerlink,.rst-content h2 .nav .icon-large.headerlink,.nav .rst-content h3 .icon-large.headerlink,.rst-content h3 .nav .icon-large.headerlink,.nav .rst-content h4 .icon-large.headerlink,.rst-content h4 .nav .icon-large.headerlink,.nav .rst-content h5 .icon-large.headerlink,.rst-content h5 .nav .icon-large.headerlink,.nav .rst-content h6 .icon-large.headerlink,.rst-content h6 .nav .icon-large.headerlink,.nav .rst-content dl dt .icon-large.headerlink,.rst-content dl dt .nav .icon-large.headerlink{line-height:0.9em}.btn .icon.icon-spin,.btn .wy-inline-validate.wy-inline-validate-success .icon-spin.wy-input-context,.wy-inline-validate.wy-inline-validate-success .btn .icon-spin.wy-input-context,.btn .wy-inline-validate.wy-inline-validate-danger .icon-spin.wy-input-context,.wy-inline-validate.wy-inline-validate-danger .btn .icon-spin.wy-input-context,.btn .wy-inline-validate.wy-inline-validate-warning .icon-spin.wy-input-context,.wy-inline-validate.wy-inline-validate-warning .btn .icon-spin.wy-input-context,.btn .wy-inline-validate.wy-inline-validate-info .icon-spin.wy-input-context,.wy-inline-validate.wy-inline-validate-info .btn .icon-spin.wy-input-context,.btn .wy-tag-input-group .wy-tag .icon-spin.wy-tag-remove,.wy-tag-input-group .wy-tag .btn .icon-spin.wy-tag-remove,.btn .rst-content .icon-spin.admonition-title,.rst-content .btn .icon-spin.admonition-title,.btn .rst-content h1 .icon-spin.headerlink,.rst-content h1 .btn .icon-spin.headerlink,.btn .rst-content h2 .icon-spin.headerlink,.rst-content h2 .btn .icon-spin.headerlink,.btn .rst-content h3 .icon-spin.headerlink,.rst-content h3 .btn .icon-spin.headerlink,.btn .rst-content h4 .icon-spin.headerlink,.rst-content h4 .btn .icon-spin.headerlink,.btn .rst-content h5 .icon-spin.headerlink,.rst-content h5 .btn .icon-spin.headerlink,.btn .rst-content h6 .icon-spin.headerlink,.rst-content h6 .btn .icon-spin.headerlink,.btn .rst-content dl dt .icon-spin.headerlink,.rst-content dl dt .btn .icon-spin.headerlink,.nav .icon.icon-spin,.nav .wy-inline-validate.wy-inline-validate-success .icon-spin.wy-input-context,.wy-inline-validate.wy-inline-validate-success .nav .icon-spin.wy-input-context,.nav .wy-inline-validate.wy-inline-validate-danger .icon-spin.wy-input-context,.wy-inline-validate.wy-inline-validate-danger .nav .icon-spin.wy-input-context,.nav .wy-inline-validate.wy-inline-validate-warning .icon-spin.wy-input-context,.wy-inline-validate.wy-inline-validate-warning .nav .icon-spin.wy-input-context,.nav .wy-inline-validate.wy-inline-validate-info .icon-spin.wy-input-context,.wy-inline-validate.wy-inline-validate-info .nav .icon-spin.wy-input-context,.nav .wy-tag-input-group .wy-tag .icon-spin.wy-tag-remove,.wy-tag-input-group .wy-tag .nav .icon-spin.wy-tag-remove,.nav .rst-content .icon-spin.admonition-title,.rst-content .nav .icon-spin.admonition-title,.nav .rst-content h1 .icon-spin.headerlink,.rst-content h1 .nav .icon-spin.headerlink,.nav .rst-content h2 .icon-spin.headerlink,.rst-content h2 .nav .icon-spin.headerlink,.nav .rst-content h3 .icon-spin.headerlink,.rst-content h3 .nav .icon-spin.headerlink,.nav .rst-content h4 .icon-spin.headerlink,.rst-content h4 .nav .icon-spin.headerlink,.nav .rst-content h5 .icon-spin.headerlink,.rst-content h5 .nav .icon-spin.headerlink,.nav .rst-content h6 .icon-spin.headerlink,.rst-content h6 .nav .icon-spin.headerlink,.nav .rst-content dl dt .icon-spin.headerlink,.rst-content dl dt .nav .icon-spin.headerlink{display:inline-block}.btn.icon:before,.wy-inline-validate.wy-inline-validate-success .btn.wy-input-context:before,.wy-inline-validate.wy-inline-validate-danger .btn.wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .btn.wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .btn.wy-input-context:before,.wy-tag-input-group .wy-tag .btn.wy-tag-remove:before,.rst-content .btn.admonition-title:before,.rst-content h1 .btn.headerlink:before,.rst-content h2 .btn.headerlink:before,.rst-content h3 .btn.headerlink:before,.rst-content h4 .btn.headerlink:before,.rst-content h5 .btn.headerlink:before,.rst-content h6 .btn.headerlink:before,.rst-content dl dt .btn.headerlink:before{opacity:0.5;-webkit-transition:opacity 0.05s ease-in;-moz-transition:opacity 0.05s ease-in;transition:opacity 0.05s ease-in}.btn.icon:hover:before,.wy-inline-validate.wy-inline-validate-success .btn.wy-input-context:hover:before,.wy-inline-validate.wy-inline-validate-danger .btn.wy-input-context:hover:before,.wy-inline-validate.wy-inline-validate-warning .btn.wy-input-context:hover:before,.wy-inline-validate.wy-inline-validate-info .btn.wy-input-context:hover:before,.wy-tag-input-group .wy-tag .btn.wy-tag-remove:hover:before,.rst-content .btn.admonition-title:hover:before,.rst-content h1 .btn.headerlink:hover:before,.rst-content h2 .btn.headerlink:hover:before,.rst-content h3 .btn.headerlink:hover:before,.rst-content h4 .btn.headerlink:hover:before,.rst-content h5 .btn.headerlink:hover:before,.rst-content h6 .btn.headerlink:hover:before,.rst-content dl dt .btn.headerlink:hover:before{opacity:1}.btn-mini .icon:before,.btn-mini .wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-success .btn-mini .wy-input-context:before,.btn-mini .wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-danger .btn-mini .wy-input-context:before,.btn-mini .wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .btn-mini .wy-input-context:before,.btn-mini .wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .btn-mini .wy-input-context:before,.btn-mini .wy-tag-input-group .wy-tag .wy-tag-remove:before,.wy-tag-input-group .wy-tag .btn-mini .wy-tag-remove:before,.btn-mini .rst-content .admonition-title:before,.rst-content .btn-mini .admonition-title:before,.btn-mini .rst-content h1 .headerlink:before,.rst-content h1 .btn-mini .headerlink:before,.btn-mini .rst-content h2 .headerlink:before,.rst-content h2 .btn-mini .headerlink:before,.btn-mini .rst-content h3 .headerlink:before,.rst-content h3 .btn-mini .headerlink:before,.btn-mini .rst-content h4 .headerlink:before,.rst-content h4 .btn-mini .headerlink:before,.btn-mini .rst-content h5 .headerlink:before,.rst-content h5 .btn-mini .headerlink:before,.btn-mini .rst-content h6 .headerlink:before,.rst-content h6 .btn-mini .headerlink:before,.btn-mini .rst-content dl dt .headerlink:before,.rst-content dl dt .btn-mini .headerlink:before{font-size:14px;vertical-align:-15%}li .icon,li .wy-inline-validate.wy-inline-validate-success .wy-input-context,.wy-inline-validate.wy-inline-validate-success li .wy-input-context,li .wy-inline-validate.wy-inline-validate-danger .wy-input-context,.wy-inline-validate.wy-inline-validate-danger li .wy-input-context,li .wy-inline-validate.wy-inline-validate-warning .wy-input-context,.wy-inline-validate.wy-inline-validate-warning li .wy-input-context,li .wy-inline-validate.wy-inline-validate-info .wy-input-context,.wy-inline-validate.wy-inline-validate-info li .wy-input-context,li .wy-tag-input-group .wy-tag .wy-tag-remove,.wy-tag-input-group .wy-tag li .wy-tag-remove,li .rst-content .admonition-title,.rst-content li .admonition-title,li .rst-content h1 .headerlink,.rst-content h1 li .headerlink,li .rst-content h2 .headerlink,.rst-content h2 li .headerlink,li .rst-content h3 .headerlink,.rst-content h3 li .headerlink,li .rst-content h4 .headerlink,.rst-content h4 li .headerlink,li .rst-content h5 .headerlink,.rst-content h5 li .headerlink,li .rst-content h6 .headerlink,.rst-content h6 li .headerlink,li .rst-content dl dt .headerlink,.rst-content dl dt li .headerlink{display:inline-block}li .icon-large:before,li .icon-large:before{width:1.875em}ul.icons{list-style-type:none;margin-left:2em;text-indent:-0.8em}ul.icons li .icon,ul.icons li .wy-inline-validate.wy-inline-validate-success .wy-input-context,.wy-inline-validate.wy-inline-validate-success ul.icons li .wy-input-context,ul.icons li .wy-inline-validate.wy-inline-validate-danger .wy-input-context,.wy-inline-validate.wy-inline-validate-danger ul.icons li .wy-input-context,ul.icons li .wy-inline-validate.wy-inline-validate-warning .wy-input-context,.wy-inline-validate.wy-inline-validate-warning ul.icons li .wy-input-context,ul.icons li .wy-inline-validate.wy-inline-validate-info .wy-input-context,.wy-inline-validate.wy-inline-validate-info ul.icons li .wy-input-context,ul.icons li .wy-tag-input-group .wy-tag .wy-tag-remove,.wy-tag-input-group .wy-tag ul.icons li .wy-tag-remove,ul.icons li .rst-content .admonition-title,.rst-content ul.icons li .admonition-title,ul.icons li .rst-content h1 .headerlink,.rst-content h1 ul.icons li .headerlink,ul.icons li .rst-content h2 .headerlink,.rst-content h2 ul.icons li .headerlink,ul.icons li .rst-content h3 .headerlink,.rst-content h3 ul.icons li .headerlink,ul.icons li .rst-content h4 .headerlink,.rst-content h4 ul.icons li .headerlink,ul.icons li .rst-content h5 .headerlink,.rst-content h5 ul.icons li .headerlink,ul.icons li .rst-content h6 .headerlink,.rst-content h6 ul.icons li .headerlink,ul.icons li .rst-content dl dt .headerlink,.rst-content dl dt ul.icons li .headerlink{width:0.8em}ul.icons li .icon-large:before,ul.icons li .icon-large:before{vertical-align:baseline}.icon-glass:before{content:"\f000"}.icon-music:before{content:"\f001"}.icon-search:before{content:"\f002"}.icon-envelope-alt:before{content:"\f003"}.icon-heart:before{content:"\f004"}.icon-star:before{content:"\f005"}.icon-star-empty:before{content:"\f006"}.icon-user:before{content:"\f007"}.icon-film:before{content:"\f008"}.icon-th-large:before{content:"\f009"}.icon-th:before{content:"\f00a"}.icon-th-list:before{content:"\f00b"}.icon-ok:before{content:"\f00c"}.icon-remove:before,.wy-tag-input-group .wy-tag .wy-tag-remove:before{content:"\f00d"}.icon-zoom-in:before{content:"\f00e"}.icon-zoom-out:before{content:"\f010"}.icon-power-off:before,.icon-off:before{content:"\f011"}.icon-signal:before{content:"\f012"}.icon-gear:before,.icon-cog:before{content:"\f013"}.icon-trash:before{content:"\f014"}.icon-home:before{content:"\f015"}.icon-file-alt:before{content:"\f016"}.icon-time:before{content:"\f017"}.icon-road:before{content:"\f018"}.icon-download-alt:before{content:"\f019"}.icon-download:before{content:"\f01a"}.icon-upload:before{content:"\f01b"}.icon-inbox:before{content:"\f01c"}.icon-play-circle:before{content:"\f01d"}.icon-rotate-right:before,.icon-repeat:before{content:"\f01e"}.icon-refresh:before{content:"\f021"}.icon-list-alt:before{content:"\f022"}.icon-lock:before{content:"\f023"}.icon-flag:before{content:"\f024"}.icon-headphones:before{content:"\f025"}.icon-volume-off:before{content:"\f026"}.icon-volume-down:before{content:"\f027"}.icon-volume-up:before{content:"\f028"}.icon-qrcode:before{content:"\f029"}.icon-barcode:before{content:"\f02a"}.icon-tag:before{content:"\f02b"}.icon-tags:before{content:"\f02c"}.icon-book:before{content:"\f02d"}.icon-bookmark:before{content:"\f02e"}.icon-print:before{content:"\f02f"}.icon-camera:before{content:"\f030"}.icon-font:before{content:"\f031"}.icon-bold:before{content:"\f032"}.icon-italic:before{content:"\f033"}.icon-text-height:before{content:"\f034"}.icon-text-width:before{content:"\f035"}.icon-align-left:before{content:"\f036"}.icon-align-center:before{content:"\f037"}.icon-align-right:before{content:"\f038"}.icon-align-justify:before{content:"\f039"}.icon-list:before{content:"\f03a"}.icon-indent-left:before{content:"\f03b"}.icon-indent-right:before{content:"\f03c"}.icon-facetime-video:before{content:"\f03d"}.icon-picture:before{content:"\f03e"}.icon-pencil:before{content:"\f040"}.icon-map-marker:before{content:"\f041"}.icon-adjust:before{content:"\f042"}.icon-tint:before{content:"\f043"}.icon-edit:before{content:"\f044"}.icon-share:before{content:"\f045"}.icon-check:before{content:"\f046"}.icon-move:before{content:"\f047"}.icon-step-backward:before{content:"\f048"}.icon-fast-backward:before{content:"\f049"}.icon-backward:before{content:"\f04a"}.icon-play:before{content:"\f04b"}.icon-pause:before{content:"\f04c"}.icon-stop:before{content:"\f04d"}.icon-forward:before{content:"\f04e"}.icon-fast-forward:before{content:"\f050"}.icon-step-forward:before{content:"\f051"}.icon-eject:before{content:"\f052"}.icon-chevron-left:before{content:"\f053"}.icon-chevron-right:before{content:"\f054"}.icon-plus-sign:before{content:"\f055"}.icon-minus-sign:before{content:"\f056"}.icon-remove-sign:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before{content:"\f057"}.icon-ok-sign:before{content:"\f058"}.icon-question-sign:before{content:"\f059"}.icon-info-sign:before{content:"\f05a"}.icon-screenshot:before{content:"\f05b"}.icon-remove-circle:before{content:"\f05c"}.icon-ok-circle:before{content:"\f05d"}.icon-ban-circle:before{content:"\f05e"}.icon-arrow-left:before{content:"\f060"}.icon-arrow-right:before{content:"\f061"}.icon-arrow-up:before{content:"\f062"}.icon-arrow-down:before{content:"\f063"}.icon-mail-forward:before,.icon-share-alt:before{content:"\f064"}.icon-resize-full:before{content:"\f065"}.icon-resize-small:before{content:"\f066"}.icon-plus:before{content:"\f067"}.icon-minus:before{content:"\f068"}.icon-asterisk:before{content:"\f069"}.icon-exclamation-sign:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.rst-content .admonition-title:before{content:"\f06a"}.icon-gift:before{content:"\f06b"}.icon-leaf:before{content:"\f06c"}.icon-fire:before{content:"\f06d"}.icon-eye-open:before{content:"\f06e"}.icon-eye-close:before{content:"\f070"}.icon-warning-sign:before{content:"\f071"}.icon-plane:before{content:"\f072"}.icon-calendar:before{content:"\f073"}.icon-random:before{content:"\f074"}.icon-comment:before{content:"\f075"}.icon-magnet:before{content:"\f076"}.icon-chevron-up:before{content:"\f077"}.icon-chevron-down:before{content:"\f078"}.icon-retweet:before{content:"\f079"}.icon-shopping-cart:before{content:"\f07a"}.icon-folder-close:before{content:"\f07b"}.icon-folder-open:before{content:"\f07c"}.icon-resize-vertical:before{content:"\f07d"}.icon-resize-horizontal:before{content:"\f07e"}.icon-bar-chart:before{content:"\f080"}.icon-twitter-sign:before{content:"\f081"}.icon-facebook-sign:before{content:"\f082"}.icon-camera-retro:before{content:"\f083"}.icon-key:before{content:"\f084"}.icon-gears:before,.icon-cogs:before{content:"\f085"}.icon-comments:before{content:"\f086"}.icon-thumbs-up-alt:before{content:"\f087"}.icon-thumbs-down-alt:before{content:"\f088"}.icon-star-half:before{content:"\f089"}.icon-heart-empty:before{content:"\f08a"}.icon-signout:before{content:"\f08b"}.icon-linkedin-sign:before{content:"\f08c"}.icon-pushpin:before{content:"\f08d"}.icon-external-link:before{content:"\f08e"}.icon-signin:before{content:"\f090"}.icon-trophy:before{content:"\f091"}.icon-github-sign:before{content:"\f092"}.icon-upload-alt:before{content:"\f093"}.icon-lemon:before{content:"\f094"}.icon-phone:before{content:"\f095"}.icon-unchecked:before,.icon-check-empty:before{content:"\f096"}.icon-bookmark-empty:before{content:"\f097"}.icon-phone-sign:before{content:"\f098"}.icon-twitter:before{content:"\f099"}.icon-facebook:before{content:"\f09a"}.icon-github:before{content:"\f09b"}.icon-unlock:before{content:"\f09c"}.icon-credit-card:before{content:"\f09d"}.icon-rss:before{content:"\f09e"}.icon-hdd:before{content:"\f0a0"}.icon-bullhorn:before{content:"\f0a1"}.icon-bell:before{content:"\f0a2"}.icon-certificate:before{content:"\f0a3"}.icon-hand-right:before{content:"\f0a4"}.icon-hand-left:before{content:"\f0a5"}.icon-hand-up:before{content:"\f0a6"}.icon-hand-down:before{content:"\f0a7"}.icon-circle-arrow-left:before{content:"\f0a8"}.icon-circle-arrow-right:before{content:"\f0a9"}.icon-circle-arrow-up:before{content:"\f0aa"}.icon-circle-arrow-down:before{content:"\f0ab"}.icon-globe:before{content:"\f0ac"}.icon-wrench:before{content:"\f0ad"}.icon-tasks:before{content:"\f0ae"}.icon-filter:before{content:"\f0b0"}.icon-briefcase:before{content:"\f0b1"}.icon-fullscreen:before{content:"\f0b2"}.icon-group:before{content:"\f0c0"}.icon-link:before{content:"\f0c1"}.icon-cloud:before{content:"\f0c2"}.icon-beaker:before{content:"\f0c3"}.icon-cut:before{content:"\f0c4"}.icon-copy:before{content:"\f0c5"}.icon-paperclip:before,.icon-paper-clip:before{content:"\f0c6"}.icon-save:before{content:"\f0c7"}.icon-sign-blank:before{content:"\f0c8"}.icon-reorder:before{content:"\f0c9"}.icon-list-ul:before{content:"\f0ca"}.icon-list-ol:before{content:"\f0cb"}.icon-strikethrough:before{content:"\f0cc"}.icon-underline:before{content:"\f0cd"}.icon-table:before{content:"\f0ce"}.icon-magic:before{content:"\f0d0"}.icon-truck:before{content:"\f0d1"}.icon-pinterest:before{content:"\f0d2"}.icon-pinterest-sign:before{content:"\f0d3"}.icon-google-plus-sign:before{content:"\f0d4"}.icon-google-plus:before{content:"\f0d5"}.icon-money:before{content:"\f0d6"}.icon-caret-down:before{content:"\f0d7"}.icon-caret-up:before{content:"\f0d8"}.icon-caret-left:before{content:"\f0d9"}.icon-caret-right:before{content:"\f0da"}.icon-columns:before{content:"\f0db"}.icon-sort:before{content:"\f0dc"}.icon-sort-down:before{content:"\f0dd"}.icon-sort-up:before{content:"\f0de"}.icon-envelope:before{content:"\f0e0"}.icon-linkedin:before{content:"\f0e1"}.icon-rotate-left:before,.icon-undo:before{content:"\f0e2"}.icon-legal:before{content:"\f0e3"}.icon-dashboard:before{content:"\f0e4"}.icon-comment-alt:before{content:"\f0e5"}.icon-comments-alt:before{content:"\f0e6"}.icon-bolt:before{content:"\f0e7"}.icon-sitemap:before{content:"\f0e8"}.icon-umbrella:before{content:"\f0e9"}.icon-paste:before{content:"\f0ea"}.icon-lightbulb:before{content:"\f0eb"}.icon-exchange:before{content:"\f0ec"}.icon-cloud-download:before{content:"\f0ed"}.icon-cloud-upload:before{content:"\f0ee"}.icon-user-md:before{content:"\f0f0"}.icon-stethoscope:before{content:"\f0f1"}.icon-suitcase:before{content:"\f0f2"}.icon-bell-alt:before{content:"\f0f3"}.icon-coffee:before{content:"\f0f4"}.icon-food:before{content:"\f0f5"}.icon-file-text-alt:before{content:"\f0f6"}.icon-building:before{content:"\f0f7"}.icon-hospital:before{content:"\f0f8"}.icon-ambulance:before{content:"\f0f9"}.icon-medkit:before{content:"\f0fa"}.icon-fighter-jet:before{content:"\f0fb"}.icon-beer:before{content:"\f0fc"}.icon-h-sign:before{content:"\f0fd"}.icon-plus-sign-alt:before{content:"\f0fe"}.icon-double-angle-left:before{content:"\f100"}.icon-double-angle-right:before{content:"\f101"}.icon-double-angle-up:before{content:"\f102"}.icon-double-angle-down:before{content:"\f103"}.icon-angle-left:before{content:"\f104"}.icon-angle-right:before{content:"\f105"}.icon-angle-up:before{content:"\f106"}.icon-angle-down:before{content:"\f107"}.icon-desktop:before{content:"\f108"}.icon-laptop:before{content:"\f109"}.icon-tablet:before{content:"\f10a"}.icon-mobile-phone:before{content:"\f10b"}.icon-circle-blank:before{content:"\f10c"}.icon-quote-left:before{content:"\f10d"}.icon-quote-right:before{content:"\f10e"}.icon-spinner:before{content:"\f110"}.icon-circle:before{content:"\f111"}.icon-mail-reply:before,.icon-reply:before{content:"\f112"}.icon-github-alt:before{content:"\f113"}.icon-folder-close-alt:before{content:"\f114"}.icon-folder-open-alt:before{content:"\f115"}.icon-expand-alt:before{content:"\f116"}.icon-collapse-alt:before{content:"\f117"}.icon-smile:before{content:"\f118"}.icon-frown:before{content:"\f119"}.icon-meh:before{content:"\f11a"}.icon-gamepad:before{content:"\f11b"}.icon-keyboard:before{content:"\f11c"}.icon-flag-alt:before{content:"\f11d"}.icon-flag-checkered:before{content:"\f11e"}.icon-terminal:before{content:"\f120"}.icon-code:before{content:"\f121"}.icon-reply-all:before{content:"\f122"}.icon-mail-reply-all:before{content:"\f122"}.icon-star-half-full:before,.icon-star-half-empty:before{content:"\f123"}.icon-location-arrow:before{content:"\f124"}.icon-crop:before{content:"\f125"}.icon-code-fork:before{content:"\f126"}.icon-unlink:before{content:"\f127"}.icon-question:before{content:"\f128"}.icon-info:before{content:"\f129"}.icon-exclamation:before{content:"\f12a"}.icon-superscript:before{content:"\f12b"}.icon-subscript:before{content:"\f12c"}.icon-eraser:before{content:"\f12d"}.icon-puzzle-piece:before{content:"\f12e"}.icon-microphone:before{content:"\f130"}.icon-microphone-off:before{content:"\f131"}.icon-shield:before{content:"\f132"}.icon-calendar-empty:before{content:"\f133"}.icon-fire-extinguisher:before{content:"\f134"}.icon-rocket:before{content:"\f135"}.icon-maxcdn:before{content:"\f136"}.icon-chevron-sign-left:before{content:"\f137"}.icon-chevron-sign-right:before{content:"\f138"}.icon-chevron-sign-up:before{content:"\f139"}.icon-chevron-sign-down:before{content:"\f13a"}.icon-html5:before{content:"\f13b"}.icon-css3:before{content:"\f13c"}.icon-anchor:before{content:"\f13d"}.icon-unlock-alt:before{content:"\f13e"}.icon-bullseye:before{content:"\f140"}.icon-ellipsis-horizontal:before{content:"\f141"}.icon-ellipsis-vertical:before{content:"\f142"}.icon-rss-sign:before{content:"\f143"}.icon-play-sign:before{content:"\f144"}.icon-ticket:before{content:"\f145"}.icon-minus-sign-alt:before{content:"\f146"}.icon-check-minus:before{content:"\f147"}.icon-level-up:before{content:"\f148"}.icon-level-down:before{content:"\f149"}.icon-check-sign:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before{content:"\f14a"}.icon-edit-sign:before{content:"\f14b"}.icon-external-link-sign:before{content:"\f14c"}.icon-share-sign:before{content:"\f14d"}.icon-compass:before{content:"\f14e"}.icon-collapse:before{content:"\f150"}.icon-collapse-top:before{content:"\f151"}.icon-expand:before{content:"\f152"}.icon-euro:before,.icon-eur:before{content:"\f153"}.icon-gbp:before{content:"\f154"}.icon-dollar:before,.icon-usd:before{content:"\f155"}.icon-rupee:before,.icon-inr:before{content:"\f156"}.icon-yen:before,.icon-jpy:before{content:"\f157"}.icon-renminbi:before,.icon-cny:before{content:"\f158"}.icon-won:before,.icon-krw:before{content:"\f159"}.icon-bitcoin:before,.icon-btc:before{content:"\f15a"}.icon-file:before{content:"\f15b"}.icon-file-text:before{content:"\f15c"}.icon-sort-by-alphabet:before{content:"\f15d"}.icon-sort-by-alphabet-alt:before{content:"\f15e"}.icon-sort-by-attributes:before{content:"\f160"}.icon-sort-by-attributes-alt:before{content:"\f161"}.icon-sort-by-order:before{content:"\f162"}.icon-sort-by-order-alt:before{content:"\f163"}.icon-thumbs-up:before{content:"\f164"}.icon-thumbs-down:before{content:"\f165"}.icon-youtube-sign:before{content:"\f166"}.icon-youtube:before{content:"\f167"}.icon-xing:before{content:"\f168"}.icon-xing-sign:before{content:"\f169"}.icon-youtube-play:before{content:"\f16a"}.icon-dropbox:before{content:"\f16b"}.icon-stackexchange:before{content:"\f16c"}.icon-instagram:before{content:"\f16d"}.icon-flickr:before{content:"\f16e"}.icon-adn:before{content:"\f170"}.icon-bitbucket:before{content:"\f171"}.icon-bitbucket-sign:before{content:"\f172"}.icon-tumblr:before{content:"\f173"}.icon-tumblr-sign:before{content:"\f174"}.icon-long-arrow-down:before{content:"\f175"}.icon-long-arrow-up:before{content:"\f176"}.icon-long-arrow-left:before{content:"\f177"}.icon-long-arrow-right:before{content:"\f178"}.icon-apple:before{content:"\f179"}.icon-windows:before{content:"\f17a"}.icon-android:before{content:"\f17b"}.icon-linux:before{content:"\f17c"}.icon-dribbble:before{content:"\f17d"}.icon-skype:before{content:"\f17e"}.icon-foursquare:before{content:"\f180"}.icon-trello:before{content:"\f181"}.icon-female:before{content:"\f182"}.icon-male:before{content:"\f183"}.icon-gittip:before{content:"\f184"}.icon-sun:before{content:"\f185"}.icon-moon:before{content:"\f186"}.icon-archive:before{content:"\f187"}.icon-bug:before{content:"\f188"}.icon-vk:before{content:"\f189"}.icon-weibo:before{content:"\f18a"}.icon-renren:before{content:"\f18b"}.wy-alert,.rst-content .note,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .tip,.rst-content .warning,.rst-content .seealso{padding:12px;line-height:24px;margin-bottom:24px}.wy-alert-title,.rst-content .admonition-title{color:#fff;font-weight:bold;display:block;color:#fff;background:transparent;margin:-12px;padding:6px 12px;margin-bottom:12px}.wy-alert.wy-alert-danger,.rst-content .wy-alert-danger.note,.rst-content .wy-alert-danger.attention,.rst-content .wy-alert-danger.caution,.rst-content .danger,.rst-content .error,.rst-content .wy-alert-danger.hint,.rst-content .wy-alert-danger.important,.rst-content .wy-alert-danger.tip,.rst-content .wy-alert-danger.warning,.rst-content .wy-alert-danger.seealso{background:#fdf3f2}.wy-alert.wy-alert-danger .wy-alert-title,.rst-content .wy-alert-danger.note .wy-alert-title,.rst-content .wy-alert-danger.attention .wy-alert-title,.rst-content .wy-alert-danger.caution .wy-alert-title,.rst-content .danger .wy-alert-title,.rst-content .error .wy-alert-title,.rst-content .wy-alert-danger.hint .wy-alert-title,.rst-content .wy-alert-danger.important .wy-alert-title,.rst-content .wy-alert-danger.tip .wy-alert-title,.rst-content .wy-alert-danger.warning .wy-alert-title,.rst-content .wy-alert-danger.seealso .wy-alert-title,.wy-alert.wy-alert-danger .rst-content .admonition-title,.rst-content .wy-alert.wy-alert-danger .admonition-title,.rst-content .wy-alert-danger.note .admonition-title,.rst-content .wy-alert-danger.attention .admonition-title,.rst-content .wy-alert-danger.caution .admonition-title,.rst-content .danger .admonition-title,.rst-content .error .admonition-title,.rst-content .wy-alert-danger.hint .admonition-title,.rst-content .wy-alert-danger.important .admonition-title,.rst-content .wy-alert-danger.tip .admonition-title,.rst-content .wy-alert-danger.warning .admonition-title,.rst-content .wy-alert-danger.seealso .admonition-title{background:#f29f97}.wy-alert.wy-alert-warning,.rst-content .wy-alert-warning.note,.rst-content .attention,.rst-content .caution,.rst-content .wy-alert-warning.danger,.rst-content .wy-alert-warning.error,.rst-content .wy-alert-warning.hint,.rst-content .wy-alert-warning.important,.rst-content .wy-alert-warning.tip,.rst-content .warning,.rst-content .wy-alert-warning.seealso{background:#ffedcc}.wy-alert.wy-alert-warning .wy-alert-title,.rst-content .wy-alert-warning.note .wy-alert-title,.rst-content .attention .wy-alert-title,.rst-content .caution .wy-alert-title,.rst-content .wy-alert-warning.danger .wy-alert-title,.rst-content .wy-alert-warning.error .wy-alert-title,.rst-content .wy-alert-warning.hint .wy-alert-title,.rst-content .wy-alert-warning.important .wy-alert-title,.rst-content .wy-alert-warning.tip .wy-alert-title,.rst-content .warning .wy-alert-title,.rst-content .wy-alert-warning.seealso .wy-alert-title,.wy-alert.wy-alert-warning .rst-content .admonition-title,.rst-content .wy-alert.wy-alert-warning .admonition-title,.rst-content .wy-alert-warning.note .admonition-title,.rst-content .attention .admonition-title,.rst-content .caution .admonition-title,.rst-content .wy-alert-warning.danger .admonition-title,.rst-content .wy-alert-warning.error .admonition-title,.rst-content .wy-alert-warning.hint .admonition-title,.rst-content .wy-alert-warning.important .admonition-title,.rst-content .wy-alert-warning.tip .admonition-title,.rst-content .warning .admonition-title,.rst-content .wy-alert-warning.seealso .admonition-title{background:#f0b37e}.wy-alert.wy-alert-info,.rst-content .note,.rst-content .wy-alert-info.attention,.rst-content .wy-alert-info.caution,.rst-content .wy-alert-info.danger,.rst-content .wy-alert-info.error,.rst-content .wy-alert-info.hint,.rst-content .wy-alert-info.important,.rst-content .wy-alert-info.tip,.rst-content .wy-alert-info.warning,.rst-content .seealso{background:#e7f2fa}.wy-alert.wy-alert-info .wy-alert-title,.rst-content .note .wy-alert-title,.rst-content .wy-alert-info.attention .wy-alert-title,.rst-content .wy-alert-info.caution .wy-alert-title,.rst-content .wy-alert-info.danger .wy-alert-title,.rst-content .wy-alert-info.error .wy-alert-title,.rst-content .wy-alert-info.hint .wy-alert-title,.rst-content .wy-alert-info.important .wy-alert-title,.rst-content .wy-alert-info.tip .wy-alert-title,.rst-content .wy-alert-info.warning .wy-alert-title,.rst-content .seealso .wy-alert-title,.wy-alert.wy-alert-info .rst-content .admonition-title,.rst-content .wy-alert.wy-alert-info .admonition-title,.rst-content .note .admonition-title,.rst-content .wy-alert-info.attention .admonition-title,.rst-content .wy-alert-info.caution .admonition-title,.rst-content .wy-alert-info.danger .admonition-title,.rst-content .wy-alert-info.error .admonition-title,.rst-content .wy-alert-info.hint .admonition-title,.rst-content .wy-alert-info.important .admonition-title,.rst-content .wy-alert-info.tip .admonition-title,.rst-content .wy-alert-info.warning .admonition-title,.rst-content .seealso .admonition-title{background:#6ab0de}.wy-alert.wy-alert-success,.rst-content .wy-alert-success.note,.rst-content .wy-alert-success.attention,.rst-content .wy-alert-success.caution,.rst-content .wy-alert-success.danger,.rst-content .wy-alert-success.error,.rst-content .hint,.rst-content .important,.rst-content .tip,.rst-content .wy-alert-success.warning,.rst-content .wy-alert-success.seealso{background:#dbfaf4}.wy-alert.wy-alert-success .wy-alert-title,.rst-content .wy-alert-success.note .wy-alert-title,.rst-content .wy-alert-success.attention .wy-alert-title,.rst-content .wy-alert-success.caution .wy-alert-title,.rst-content .wy-alert-success.danger .wy-alert-title,.rst-content .wy-alert-success.error .wy-alert-title,.rst-content .hint .wy-alert-title,.rst-content .important .wy-alert-title,.rst-content .tip .wy-alert-title,.rst-content .wy-alert-success.warning .wy-alert-title,.rst-content .wy-alert-success.seealso .wy-alert-title,.wy-alert.wy-alert-success .rst-content .admonition-title,.rst-content .wy-alert.wy-alert-success .admonition-title,.rst-content .wy-alert-success.note .admonition-title,.rst-content .wy-alert-success.attention .admonition-title,.rst-content .wy-alert-success.caution .admonition-title,.rst-content .wy-alert-success.danger .admonition-title,.rst-content .wy-alert-success.error .admonition-title,.rst-content .hint .admonition-title,.rst-content .important .admonition-title,.rst-content .tip .admonition-title,.rst-content .wy-alert-success.warning .admonition-title,.rst-content .wy-alert-success.seealso .admonition-title{background:#1abc9c}.wy-alert.wy-alert-neutral,.rst-content .wy-alert-neutral.note,.rst-content .wy-alert-neutral.attention,.rst-content .wy-alert-neutral.caution,.rst-content .wy-alert-neutral.danger,.rst-content .wy-alert-neutral.error,.rst-content .wy-alert-neutral.hint,.rst-content .wy-alert-neutral.important,.rst-content .wy-alert-neutral.tip,.rst-content .wy-alert-neutral.warning,.rst-content .wy-alert-neutral.seealso{background:#f3f6f6}.wy-alert.wy-alert-neutral strong,.rst-content .wy-alert-neutral.note strong,.rst-content .wy-alert-neutral.attention strong,.rst-content .wy-alert-neutral.caution strong,.rst-content .wy-alert-neutral.danger strong,.rst-content .wy-alert-neutral.error strong,.rst-content .wy-alert-neutral.hint strong,.rst-content .wy-alert-neutral.important strong,.rst-content .wy-alert-neutral.tip strong,.rst-content .wy-alert-neutral.warning strong,.rst-content .wy-alert-neutral.seealso strong{color:#404040}.wy-alert.wy-alert-neutral a,.rst-content .wy-alert-neutral.note a,.rst-content .wy-alert-neutral.attention a,.rst-content .wy-alert-neutral.caution a,.rst-content .wy-alert-neutral.danger a,.rst-content .wy-alert-neutral.error a,.rst-content .wy-alert-neutral.hint a,.rst-content .wy-alert-neutral.important a,.rst-content .wy-alert-neutral.tip a,.rst-content .wy-alert-neutral.warning a,.rst-content .wy-alert-neutral.seealso a{color:#2980b9}.wy-tray-container{position:fixed;top:-50px;left:0;width:100%;-webkit-transition:top 0.2s ease-in;-moz-transition:top 0.2s ease-in;transition:top 0.2s ease-in}.wy-tray-container.on{top:0}.wy-tray-container li{display:none;width:100%;background:#343131;padding:12px 24px;color:#fff;margin-bottom:6px;text-align:center;box-shadow:0 5px 5px 0 rgba(0,0,0,0.1),0px -1px 2px -1px rgba(255,255,255,0.5) inset}.wy-tray-container li.wy-tray-item-success{background:#27ae60}.wy-tray-container li.wy-tray-item-info{background:#2980b9}.wy-tray-container li.wy-tray-item-warning{background:#e67e22}.wy-tray-container li.wy-tray-item-danger{background:#e74c3c}.btn{display:inline-block;*display:inline;zoom:1;line-height:normal;white-space:nowrap;vertical-align:baseline;text-align:center;cursor:pointer;-webkit-user-drag:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;font-size:100%;padding:6px 12px;color:#fff;border:1px solid rgba(0,0,0,0.1);border-bottom:solid 3px rgba(0,0,0,0.1);background-color:#27ae60;text-decoration:none;font-weight:500;box-shadow:0px 1px 2px -1px rgba(255,255,255,0.5) inset;-webkit-transition:all 0.1s linear;-moz-transition:all 0.1s linear;transition:all 0.1s linear;outline-none:false}.btn-hover{background:#2e8ece;color:#fff}.btn:hover{background:#2cc36b;color:#fff}.btn:focus{background:#2cc36b;color:#fff;outline:0}.btn:active{border-top:solid 3px rgba(0,0,0,0.1);border-bottom:solid 1px rgba(0,0,0,0.1);box-shadow:0px 1px 2px -1px rgba(0,0,0,0.5) inset}.btn[disabled]{background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);filter:alpha(opacity=40);opacity:0.4;cursor:not-allowed;box-shadow:none}.btn-disabled{background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);filter:alpha(opacity=40);opacity:0.4;cursor:not-allowed;box-shadow:none}.btn-disabled:hover,.btn-disabled:focus,.btn-disabled:active{background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);filter:alpha(opacity=40);opacity:0.4;cursor:not-allowed;box-shadow:none}.btn::-moz-focus-inner{padding:0;border:0}.btn-small{font-size:80%}.btn-info{background-color:#2980b9 !important}.btn-info:hover{background-color:#2e8ece !important}.btn-neutral{background-color:#f3f6f6 !important;color:#404040 !important}.btn-neutral:hover{background-color:#e5ebeb !important;color:#404040}.btn-danger{background-color:#e74c3c !important}.btn-danger:hover{background-color:#ea6153 !important}.btn-warning{background-color:#e67e22 !important}.btn-warning:hover{background-color:#e98b39 !important}.btn-invert{background-color:#343131}.btn-invert:hover{background-color:#413d3d !important}.btn-link{background-color:transparent !important;color:#2980b9;border-color:transparent}.btn-link:hover{background-color:transparent !important;color:#409ad5;border-color:transparent}.btn-link:active{background-color:transparent !important;border-color:transparent;border-top:solid 1px transparent;border-bottom:solid 3px transparent}.wy-btn-group .btn,.wy-control .btn{vertical-align:middle}.wy-btn-group{margin-bottom:24px;*zoom:1}.wy-btn-group:before,.wy-btn-group:after{display:table;content:""}.wy-btn-group:after{clear:both}.wy-dropdown{position:relative;display:inline-block}.wy-dropdown:hover .wy-dropdown-menu{display:block}.wy-dropdown .caret:after{font-family:fontawesome-webfont;content:"\f0d7";font-size:70%}.wy-dropdown-menu{position:absolute;top:100%;left:0;display:none;float:left;min-width:100%;background:#fcfcfc;z-index:100;border:solid 1px #cfd7dd;box-shadow:0 5px 5px 0 rgba(0,0,0,0.1);padding:12px}.wy-dropdown-menu>dd>a{display:block;clear:both;color:#404040;white-space:nowrap;font-size:90%;padding:0 12px}.wy-dropdown-menu>dd>a:hover{background:#2980b9;color:#fff}.wy-dropdown-menu>dd.divider{border-top:solid 1px #cfd7dd;margin:6px 0}.wy-dropdown-menu>dd.search{padding-bottom:12px}.wy-dropdown-menu>dd.search input[type="search"]{width:100%}.wy-dropdown-menu>dd.call-to-action{background:#e3e3e3;text-transform:uppercase;font-weight:500;font-size:80%}.wy-dropdown-menu>dd.call-to-action:hover{background:#e3e3e3}.wy-dropdown-menu>dd.call-to-action .btn{color:#fff}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu{background:#fcfcfc;margin-top:2px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a{padding:6px 12px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a:hover{background:#2980b9;color:#fff}.wy-dropdown.wy-dropdown-left .wy-dropdown-menu{right:0;text-align:right}.wy-dropdown-arrow:before{content:" ";border-bottom:5px solid #f5f5f5;border-left:5px solid transparent;border-right:5px solid transparent;position:absolute;display:block;top:-4px;left:50%;margin-left:-3px}.wy-dropdown-arrow.wy-dropdown-arrow-left:before{left:11px}.wy-form-stacked select{display:block}.wy-form-aligned input,.wy-form-aligned textarea,.wy-form-aligned select,.wy-form-aligned .wy-help-inline,.wy-form-aligned label{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-form-aligned .wy-control-group>label{display:inline-block;vertical-align:middle;width:10em;margin:0.5em 1em 0 0;float:left}.wy-form-aligned .wy-control{float:left}.wy-form-aligned .wy-control label{display:block}.wy-form-aligned .wy-control select{margin-top:0.5em}fieldset{border:0;margin:0;padding:0}legend{display:block;width:100%;border:0;padding:0;white-space:normal;margin-bottom:24px;font-size:150%;*margin-left:-7px}label{display:block;margin:0 0 0.3125em 0;color:#999;font-size:90%}button,input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}button,input{line-height:normal}button{-webkit-appearance:button;cursor:pointer;*overflow:visible}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}button[disabled]{cursor:default}input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer;*overflow:visible}input[type="text"],input[type="password"],input[type="email"],input[type="url"],input[type="date"],input[type="month"],input[type="time"],input[type="datetime"],input[type="datetime-local"],input[type="week"],input[type="number"],input[type="search"],input[type="tel"],input[type="color"]{-webkit-appearance:none;padding:6px;display:inline-block;border:1px solid #ccc;font-size:80%;font-family:"Lato","proxima-nova","Helvetica Neue",Arial,sans-serif;box-shadow:inset 0 1px 3px #ddd;border-radius:0;-webkit-transition:border 0.3s linear;-moz-transition:border 0.3s linear;transition:border 0.3s linear}input[type="datetime-local"]{padding:0.34375em 0.625em}input[disabled]{cursor:default}input[type="checkbox"],input[type="radio"]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0;margin-right:0.3125em;*height:13px;*width:13px}input[type="search"]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none}input[type="text"]:focus,input[type="password"]:focus,input[type="email"]:focus,input[type="url"]:focus,input[type="date"]:focus,input[type="month"]:focus,input[type="time"]:focus,input[type="datetime"]:focus,input[type="datetime-local"]:focus,input[type="week"]:focus,input[type="number"]:focus,input[type="search"]:focus,input[type="tel"]:focus,input[type="color"]:focus{outline:0;outline:thin dotted \9;border-color:#2980b9}input.no-focus:focus{border-color:#ccc !important}input[type="file"]:focus,input[type="radio"]:focus,input[type="checkbox"]:focus{outline:thin dotted #333;outline:1px auto #129fea}input[type="text"][disabled],input[type="password"][disabled],input[type="email"][disabled],input[type="url"][disabled],input[type="date"][disabled],input[type="month"][disabled],input[type="time"][disabled],input[type="datetime"][disabled],input[type="datetime-local"][disabled],input[type="week"][disabled],input[type="number"][disabled],input[type="search"][disabled],input[type="tel"][disabled],input[type="color"][disabled]{cursor:not-allowed;background-color:#f3f6f6;color:#cad2d3}input:focus:invalid,textarea:focus:invalid,select:focus:invalid{color:#e74c3c;border:1px solid #e74c3c}input:focus:invalid:focus,textarea:focus:invalid:focus,select:focus:invalid:focus{border-color:#e9322d}input[type="file"]:focus:invalid:focus,input[type="radio"]:focus:invalid:focus,input[type="checkbox"]:focus:invalid:focus{outline-color:#e9322d}input.wy-input-large{padding:12px;font-size:100%}textarea{overflow:auto;vertical-align:top;width:100%}select,textarea{padding:0.5em 0.625em;display:inline-block;border:1px solid #ccc;font-size:0.8em;box-shadow:inset 0 1px 3px #ddd;-webkit-transition:border 0.3s linear;-moz-transition:border 0.3s linear;transition:border 0.3s linear}select{border:1px solid #ccc;background-color:#fff}select[multiple]{height:auto}select:focus,textarea:focus{outline:0}select[disabled],textarea[disabled],input[readonly],select[readonly],textarea[readonly]{cursor:not-allowed;background-color:#fff;color:#cad2d3;border-color:transparent}.wy-checkbox,.wy-radio{margin:0.5em 0;color:#404040 !important;display:block}.wy-form-message-inline{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-input-prefix,.wy-input-suffix{white-space:nowrap}.wy-input-prefix .wy-input-context,.wy-input-suffix .wy-input-context{padding:6px;display:inline-block;font-size:80%;background-color:#f3f6f6;border:solid 1px #ccc;color:#999}.wy-input-suffix .wy-input-context{border-left:0}.wy-input-prefix .wy-input-context{border-right:0}.wy-inline-validate{white-space:nowrap}.wy-inline-validate .wy-input-context{padding:0.5em 0.625em;display:inline-block;font-size:80%}.wy-inline-validate.wy-inline-validate-success .wy-input-context{color:#27ae60}.wy-inline-validate.wy-inline-validate-danger .wy-input-context{color:#e74c3c}.wy-inline-validate.wy-inline-validate-warning .wy-input-context{color:#e67e22}.wy-inline-validate.wy-inline-validate-info .wy-input-context{color:#2980b9}.wy-control-group{margin-bottom:24px;*zoom:1}.wy-control-group:before,.wy-control-group:after{display:table;content:""}.wy-control-group:after{clear:both}.wy-control-group.wy-control-group-error .wy-form-message,.wy-control-group.wy-control-group-error label{color:#e74c3c}.wy-control-group.wy-control-group-error input[type="text"],.wy-control-group.wy-control-group-error input[type="password"],.wy-control-group.wy-control-group-error input[type="email"],.wy-control-group.wy-control-group-error input[type="url"],.wy-control-group.wy-control-group-error input[type="date"],.wy-control-group.wy-control-group-error input[type="month"],.wy-control-group.wy-control-group-error input[type="time"],.wy-control-group.wy-control-group-error input[type="datetime"],.wy-control-group.wy-control-group-error input[type="datetime-local"],.wy-control-group.wy-control-group-error input[type="week"],.wy-control-group.wy-control-group-error input[type="number"],.wy-control-group.wy-control-group-error input[type="search"],.wy-control-group.wy-control-group-error input[type="tel"],.wy-control-group.wy-control-group-error input[type="color"]{border:solid 2px #e74c3c}.wy-control-group.wy-control-group-error textarea{border:solid 2px #e74c3c}.wy-control-group.fluid-input input[type="text"],.wy-control-group.fluid-input input[type="password"],.wy-control-group.fluid-input input[type="email"],.wy-control-group.fluid-input input[type="url"],.wy-control-group.fluid-input input[type="date"],.wy-control-group.fluid-input input[type="month"],.wy-control-group.fluid-input input[type="time"],.wy-control-group.fluid-input input[type="datetime"],.wy-control-group.fluid-input input[type="datetime-local"],.wy-control-group.fluid-input input[type="week"],.wy-control-group.fluid-input input[type="number"],.wy-control-group.fluid-input input[type="search"],.wy-control-group.fluid-input input[type="tel"],.wy-control-group.fluid-input input[type="color"]{width:100%}.wy-form-message-inline{display:inline-block;padding-left:0.3em;color:#666;vertical-align:middle;font-size:90%}.wy-form-message{display:block;color:#ccc;font-size:70%;margin-top:0.3125em;font-style:italic}.wy-tag-input-group{padding:4px 4px 0px 4px;display:inline-block;border:1px solid #ccc;font-size:80%;font-family:"Lato","proxima-nova","Helvetica Neue",Arial,sans-serif;box-shadow:inset 0 1px 3px #ddd;background:#fff;-webkit-transition:border 0.3s linear;-moz-transition:border 0.3s linear;transition:border 0.3s linear}.wy-tag-input-group .wy-tag{display:inline-block;background-color:rgba(0,0,0,0.1);padding:0.5em 0.625em;border-radius:2px;position:relative;margin-bottom:4px}.wy-tag-input-group .wy-tag .wy-tag-remove{color:#ccc;margin-left:5px}.wy-tag-input-group .wy-tag .wy-tag-remove:hover{color:#e74c3c}.wy-tag-input-group label{margin-left:5px;display:inline-block;margin-bottom:0}.wy-tag-input-group input{border:none;font-size:100%;margin-bottom:4px;box-shadow:none}.wy-form-upload{border:solid 1px #ccc;border-bottom:solid 3px #ccc;background-color:#fff;padding:24px;display:inline-block;text-align:center;cursor:pointer;color:#404040;-webkit-transition:border-color 0.1s ease-in;-moz-transition:border-color 0.1s ease-in;transition:border-color 0.1s ease-in;*zoom:1}.wy-form-upload:before,.wy-form-upload:after{display:table;content:""}.wy-form-upload:after{clear:both}@media screen and (max-width: 480px){.wy-form-upload{width:100%}}.wy-form-upload .image-drop{display:none}.wy-form-upload .image-desktop{display:none}.wy-form-upload .image-loading{display:none}.wy-form-upload .wy-form-upload-icon{display:block;font-size:32px;color:#b3b3b3}.wy-form-upload .image-drop .wy-form-upload-icon{color:#27ae60}.wy-form-upload p{font-size:90%}.wy-form-upload .wy-form-upload-image{float:left;margin-right:24px}@media screen and (max-width: 480px){.wy-form-upload .wy-form-upload-image{width:100%;margin-bottom:24px}}.wy-form-upload img{max-width:125px;max-height:125px;opacity:0.9;-webkit-transition:opacity 0.1s ease-in;-moz-transition:opacity 0.1s ease-in;transition:opacity 0.1s ease-in}.wy-form-upload .wy-form-upload-content{float:left}@media screen and (max-width: 480px){.wy-form-upload .wy-form-upload-content{width:100%}}.wy-form-upload:hover{border-color:#b3b3b3;color:#404040}.wy-form-upload:hover .image-desktop{display:block}.wy-form-upload:hover .image-drag{display:none}.wy-form-upload:hover img{opacity:1}.wy-form-upload:active{border-top:solid 3px #ccc;border-bottom:solid 1px #ccc}.wy-form-upload.wy-form-upload-big{width:100%;text-align:center;padding:72px}.wy-form-upload.wy-form-upload-big .wy-form-upload-content{float:none}.wy-form-upload.wy-form-upload-file p{margin-bottom:0}.wy-form-upload.wy-form-upload-file .wy-form-upload-icon{display:inline-block;font-size:inherit}.wy-form-upload.wy-form-upload-drop{background-color:#ddf7e8}.wy-form-upload.wy-form-upload-drop .image-drop{display:block}.wy-form-upload.wy-form-upload-drop .image-desktop{display:none}.wy-form-upload.wy-form-upload-drop .image-drag{display:none}.wy-form-upload.wy-form-upload-loading .image-drag{display:none}.wy-form-upload.wy-form-upload-loading .image-desktop{display:none}.wy-form-upload.wy-form-upload-loading .image-loading{display:block}.wy-form-upload.wy-form-upload-loading .wy-input-prefix{display:none}.wy-form-upload.wy-form-upload-loading p{margin-bottom:0}.rotate-90{-webkit-transform:rotate(90deg);-moz-transform:rotate(90deg);-ms-transform:rotate(90deg);-o-transform:rotate(90deg);transform:rotate(90deg)}.rotate-180{-webkit-transform:rotate(180deg);-moz-transform:rotate(180deg);-ms-transform:rotate(180deg);-o-transform:rotate(180deg);transform:rotate(180deg)}.rotate-270{-webkit-transform:rotate(270deg);-moz-transform:rotate(270deg);-ms-transform:rotate(270deg);-o-transform:rotate(270deg);transform:rotate(270deg)}.mirror{-webkit-transform:scaleX(-1);-moz-transform:scaleX(-1);-ms-transform:scaleX(-1);-o-transform:scaleX(-1);transform:scaleX(-1)}.mirror.rotate-90{-webkit-transform:scaleX(-1) rotate(90deg);-moz-transform:scaleX(-1) rotate(90deg);-ms-transform:scaleX(-1) rotate(90deg);-o-transform:scaleX(-1) rotate(90deg);transform:scaleX(-1) rotate(90deg)}.mirror.rotate-180{-webkit-transform:scaleX(-1) rotate(180deg);-moz-transform:scaleX(-1) rotate(180deg);-ms-transform:scaleX(-1) rotate(180deg);-o-transform:scaleX(-1) rotate(180deg);transform:scaleX(-1) rotate(180deg)}.mirror.rotate-270{-webkit-transform:scaleX(-1) rotate(270deg);-moz-transform:scaleX(-1) rotate(270deg);-ms-transform:scaleX(-1) rotate(270deg);-o-transform:scaleX(-1) rotate(270deg);transform:scaleX(-1) rotate(270deg)}.wy-form-gallery-manage{margin-left:-12px;margin-right:-12px}.wy-form-gallery-manage li{float:left;padding:12px;width:20%;cursor:pointer}@media screen and (max-width: 768px){.rst-content{margin-top: 65px;}.wy-nav-top{display:block;position:fixed;width:100%;}.wy-form-gallery-manage li{width:25%}}@media screen and (max-width: 480px){.wy-form-gallery-manage li{width:50%}}.wy-form-gallery-manage li:active{cursor:move}.wy-form-gallery-manage li>a{padding:12px;background-color:#fff;border:solid 1px #e1e4e5;border-bottom:solid 3px #e1e4e5;display:inline-block;-webkit-transition:all 0.1s ease-in;-moz-transition:all 0.1s ease-in;transition:all 0.1s ease-in}.wy-form-gallery-manage li>a:active{border:solid 1px #ccc;border-top:solid 3px #ccc}.wy-form-gallery-manage img{width:100%;-webkit-transition:all 0.05s ease-in;-moz-transition:all 0.05s ease-in;transition:all 0.05s ease-in}li.wy-form-gallery-edit{position:relative;color:#fff;padding:24px;width:100%;display:block;background-color:#343131;border-radius:4px}li.wy-form-gallery-edit .arrow{position:absolute;display:block;top:-50px;left:50%;margin-left:-25px;z-index:500;height:0;width:0;border-color:transparent;border-style:solid;border-width:25px;border-bottom-color:#343131}@media only screen and (max-width: 480px){.wy-form button[type="submit"]{margin:0.7em 0 0}.wy-form input[type="text"],.wy-form input[type="password"],.wy-form input[type="email"],.wy-form input[type="url"],.wy-form input[type="date"],.wy-form input[type="month"],.wy-form input[type="time"],.wy-form input[type="datetime"],.wy-form input[type="datetime-local"],.wy-form input[type="week"],.wy-form input[type="number"],.wy-form input[type="search"],.wy-form input[type="tel"],.wy-form input[type="color"]{margin-bottom:0.3em;display:block}.wy-form label{margin-bottom:0.3em;display:block}.wy-form input[type="password"],.wy-form input[type="email"],.wy-form input[type="url"],.wy-form input[type="date"],.wy-form input[type="month"],.wy-form input[type="time"],.wy-form input[type="datetime"],.wy-form input[type="datetime-local"],.wy-form input[type="week"],.wy-form input[type="number"],.wy-form input[type="search"],.wy-form input[type="tel"],.wy-form input[type="color"]{margin-bottom:0}.wy-form-aligned .wy-control-group label{margin-bottom:0.3em;text-align:left;display:block;width:100%}.wy-form-aligned .wy-controls{margin:1.5em 0 0 0}.wy-form .wy-help-inline,.wy-form-message-inline,.wy-form-message{display:block;font-size:80%;padding:0.2em 0 0.8em}}@media screen and (max-width: 768px){.tablet-hide{display:none}}@media screen and (max-width: 480px){.mobile-hide{display:none}}.float-left{float:left}.float-right{float:right}.full-width{width:100%}.wy-grid-one-col{*zoom:1;max-width:68em;margin-left:auto;margin-right:auto;max-width:1066px;margin-top:1.618em}.wy-grid-one-col:before,.wy-grid-one-col:after{display:table;content:""}.wy-grid-one-col:after{clear:both}.wy-grid-one-col section{display:block;float:left;margin-right:2.35765%;width:100%;background:#fcfcfc;padding:1.618em;margin-right:0}.wy-grid-one-col section:last-child{margin-right:0}.wy-grid-index-card{*zoom:1;max-width:68em;margin-left:auto;margin-right:auto;max-width:460px;margin-top:1.618em;background:#fcfcfc;padding:1.618em}.wy-grid-index-card:before,.wy-grid-index-card:after{display:table;content:""}.wy-grid-index-card:after{clear:both}.wy-grid-index-card header,.wy-grid-index-card section,.wy-grid-index-card aside{display:block;float:left;margin-right:2.35765%;width:100%}.wy-grid-index-card header:last-child,.wy-grid-index-card section:last-child,.wy-grid-index-card aside:last-child{margin-right:0}.wy-grid-index-card.twocol{max-width:768px}.wy-grid-index-card.twocol section{display:block;float:left;margin-right:2.35765%;width:48.82117%}.wy-grid-index-card.twocol section:last-child{margin-right:0}.wy-grid-index-card.twocol aside{display:block;float:left;margin-right:2.35765%;width:48.82117%}.wy-grid-index-card.twocol aside:last-child{margin-right:0}.wy-grid-search-filter{*zoom:1;max-width:68em;margin-left:auto;margin-right:auto;margin-bottom:24px}.wy-grid-search-filter:before,.wy-grid-search-filter:after{display:table;content:""}.wy-grid-search-filter:after{clear:both}.wy-grid-search-filter .wy-grid-search-filter-input{display:block;float:left;margin-right:2.35765%;width:74.41059%}.wy-grid-search-filter .wy-grid-search-filter-input:last-child{margin-right:0}.wy-grid-search-filter .wy-grid-search-filter-btn{display:block;float:left;margin-right:2.35765%;width:23.23176%}.wy-grid-search-filter .wy-grid-search-filter-btn:last-child{margin-right:0}.wy-table,.rst-content table.docutils,.rst-content table.field-list{border-collapse:collapse;border-spacing:0;empty-cells:show;margin-bottom:24px}.wy-table caption,.rst-content table.docutils caption,.rst-content table.field-list caption{color:#000;font:italic 85%/1 arial,sans-serif;padding:1em 0;text-align:center}.wy-table td,.rst-content table.docutils td,.rst-content table.field-list td,.wy-table th,.rst-content table.docutils th,.rst-content table.field-list th{font-size:90%;margin:0;overflow:visible;padding:8px 16px}.wy-table td:first-child,.rst-content table.docutils td:first-child,.rst-content table.field-list td:first-child,.wy-table th:first-child,.rst-content table.docutils th:first-child,.rst-content table.field-list th:first-child{border-left-width:0}.wy-table thead,.rst-content table.docutils thead,.rst-content table.field-list thead{color:#000;text-align:left;vertical-align:bottom;white-space:nowrap}.wy-table thead th,.rst-content table.docutils thead th,.rst-content table.field-list thead th{font-weight:bold;border-bottom:solid 2px #e1e4e5}.wy-table td,.rst-content table.docutils td,.rst-content table.field-list td{background-color:transparent;vertical-align:middle}.wy-table td p,.rst-content table.docutils td p,.rst-content table.field-list td p{line-height:18px;margin-bottom:0}.wy-table .wy-table-cell-min,.rst-content table.docutils .wy-table-cell-min,.rst-content table.field-list .wy-table-cell-min{width:1%;padding-right:0}.wy-table .wy-table-cell-min input[type=checkbox],.rst-content table.docutils .wy-table-cell-min input[type=checkbox],.rst-content table.field-list .wy-table-cell-min input[type=checkbox],.wy-table .wy-table-cell-min input[type=checkbox],.rst-content table.docutils .wy-table-cell-min input[type=checkbox],.rst-content table.field-list .wy-table-cell-min input[type=checkbox]{margin:0}.wy-table-secondary{color:gray;font-size:90%}.wy-table-tertiary{color:gray;font-size:80%}.wy-table-odd td,.wy-table-striped tr:nth-child(2n-1) td,.rst-content table.docutils:not(.field-list) tr:nth-child(2n-1) td{background-color:#f3f6f6}.wy-table-backed{background-color:#f3f6f6}.wy-table-bordered-all,.rst-content table.docutils{border:1px solid #e1e4e5}.wy-table-bordered-all td,.rst-content table.docutils td{border-bottom:1px solid #e1e4e5;border-left:1px solid #e1e4e5}.wy-table-bordered-all tbody>tr:last-child td,.rst-content table.docutils tbody>tr:last-child td{border-bottom-width:0}.wy-table-bordered{border:1px solid #e1e4e5}.wy-table-bordered-rows td{border-bottom:1px solid #e1e4e5}.wy-table-bordered-rows tbody>tr:last-child td{border-bottom-width:0}.wy-table-horizontal tbody>tr:last-child td{border-bottom-width:0}.wy-table-horizontal td,.wy-table-horizontal th{border-width:0 0 1px 0;border-bottom:1px solid #e1e4e5}.wy-table-horizontal tbody>tr:last-child td{border-bottom-width:0}.wy-table-responsive{margin-bottom:24px;max-width:100%;overflow:auto}.wy-table-responsive table{margin-bottom:0 !important}.wy-table-responsive table td,.wy-table-responsive table th{white-space:nowrap}html{height:100%;overflow-x:hidden}body{font-family:"Lato","proxima-nova","Helvetica Neue",Arial,sans-serif;font-weight:normal;color:#404040;min-height:100%;overflow-x:hidden;background:#edf0f2}a{color:#2980b9;text-decoration:none}a:hover{color:#3091d1}.link-danger{color:#e74c3c}.link-danger:hover{color:#d62c1a}.text-left{text-align:left}.text-center{text-align:center}.text-right{text-align:right}h1,h2,h3,h4,h5,h6,legend{margin-top:0;font-weight:700;font-family:"Roboto Slab","ff-tisa-web-pro","Georgia",Arial,sans-serif}p{line-height:24px;margin:0;font-size:16px;margin-bottom:24px}h1{font-size:175%}h2{font-size:150%}h3{font-size:125%}h4{font-size:115%}h5{font-size:110%}h6{font-size:100%}small{font-size:80%}pre,.rst-content tt{max-width:100%;background:#fff;border:solid 1px #e1e4e5;font-size:75%;padding:10px;font-family:"Incosolata","Consolata","Monaco",monospace;color:#e74c3c;overflow-x:auto}code.code-large,.rst-content tt.code-large{font-size:90%}.full-width{width:100%}.wy-plain-list-disc,.rst-content .section ul,.rst-content .toctree-wrapper ul{list-style:disc;line-height:24px;margin-bottom:24px}.wy-plain-list-disc li,.rst-content .section ul li,.rst-content .toctree-wrapper ul li{list-style:disc;margin-left:24px}.wy-plain-list-disc li ul,.rst-content .section ul li ul,.rst-content .toctree-wrapper ul li ul{margin-bottom:0}.wy-plain-list-disc li li,.rst-content .section ul li li,.rst-content .toctree-wrapper ul li li{list-style:circle}.wy-plain-list-disc li li li,.rst-content .section ul li li li,.rst-content .toctree-wrapper ul li li li{list-style:square}.wy-plain-list-decimal,.rst-content .section ol,.rst-content ol.arabic{list-style:decimal;line-height:24px;margin-bottom:24px}.wy-plain-list-decimal li,.rst-content .section ol li,.rst-content ol.arabic li{list-style:decimal;margin-left:24px}.wy-type-large{font-size:120%}.wy-type-normal{font-size:100%}.wy-type-small{font-size:100%}.wy-type-strike{text-decoration:line-through}.wy-text-warning{color:#e67e22 !important}a.wy-text-warning:hover{color:#eb9950 !important}.wy-text-info{color:#2980b9 !important}a.wy-text-info:hover{color:#409ad5 !important}.wy-text-success{color:#27ae60 !important}a.wy-text-success:hover{color:#36d278 !important}.wy-text-danger{color:#e74c3c !important}a.wy-text-danger:hover{color:#ed7669 !important}.wy-text-neutral{color:#404040 !important}a.wy-text-neutral:hover{color:#595959 !important}.codeblock-example{border:1px solid #e1e4e5;border-bottom:none;padding:24px;padding-top:48px;font-weight:500;background:#fff;position:relative}.codeblock-example:after{content:"Example";position:absolute;top:0px;left:0px;background:#9b59b6;color:#fff;padding:6px 12px}.codeblock-example.prettyprint-example-only{border:1px solid #e1e4e5;margin-bottom:24px}.codeblock,.rst-content .literal-block,div[class^='highlight']{border:1px solid #e1e4e5;padding:0px;overflow-x:auto;background:#fff;margin:1px 0 24px 0}.codeblock div[class^='highlight'],.rst-content .literal-block div[class^='highlight'],div[class^='highlight'] div[class^='highlight']{border:none;background:none;margin:0}div[class^='highlight'] td.code{width:100%}.linenodiv pre{border-right:solid 1px #e6e9ea;margin:0;padding:12px 12px;font-family:"Incosolata","Consolata","Monaco",monospace;font-size:12px;line-height:1.5;color:#d9d9d9}div[class^='highlight'] pre{white-space:pre;margin:0;padding:12px 12px;font-family:"Incosolata","Consolata","Monaco",monospace;font-size:12px;line-height:1.5;display:block;overflow:auto;color:#404040}pre.literal-block{@extends .codeblock;}@media print{.codeblock,.rst-content .literal-block,div[class^='highlight'],div[class^='highlight'] pre{white-space:pre-wrap}}.hll{background-color:#ffc;margin:0 -12px;padding:0 12px;display:block}.c{color:#998;font-style:italic}.err{color:#a61717;background-color:#e3d2d2}.k{font-weight:bold}.o{font-weight:bold}.cm{color:#998;font-style:italic}.cp{color:#999;font-weight:bold}.c1{color:#998;font-style:italic}.cs{color:#999;font-weight:bold;font-style:italic}.gd{color:#000;background-color:#fdd}.gd .x{color:#000;background-color:#faa}.ge{font-style:italic}.gr{color:#a00}.gh{color:#999}.gi{color:#000;background-color:#dfd}.gi .x{color:#000;background-color:#afa}.go{color:#888}.gp{color:#555}.gs{font-weight:bold}.gu{color:purple;font-weight:bold}.gt{color:#a00}.kc{font-weight:bold}.kd{font-weight:bold}.kn{font-weight:bold}.kp{font-weight:bold}.kr{font-weight:bold}.kt{color:#458;font-weight:bold}.m{color:#099}.s{color:#d14}.n{color:#333}.na{color:teal}.nb{color:#0086b3}.nc{color:#458;font-weight:bold}.no{color:teal}.ni{color:purple}.ne{color:#900;font-weight:bold}.nf{color:#900;font-weight:bold}.nn{color:#555}.nt{color:navy}.nv{color:teal}.ow{font-weight:bold}.w{color:#bbb}.mf{color:#099}.mh{color:#099}.mi{color:#099}.mo{color:#099}.sb{color:#d14}.sc{color:#d14}.sd{color:#d14}.s2{color:#d14}.se{color:#d14}.sh{color:#d14}.si{color:#d14}.sx{color:#d14}.sr{color:#009926}.s1{color:#d14}.ss{color:#990073}.bp{color:#999}.vc{color:teal}.vg{color:teal}.vi{color:teal}.il{color:#099}.gc{color:#999;background-color:#eaf2f5}.wy-breadcrumbs li{display:inline-block}.wy-breadcrumbs li.wy-breadcrumbs-aside{float:right}.wy-breadcrumbs li a{display:inline-block;padding:5px}.wy-breadcrumbs li a:first-child{padding-left:0}.wy-breadcrumbs-extra{margin-bottom:0;color:#b3b3b3;font-size:80%;display:inline-block}@media screen and (max-width: 480px){.wy-breadcrumbs-extra{display:none}.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}@media print{.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}.wy-affix{position:fixed;top:1.618em}.wy-menu a:hover{text-decoration:none}.wy-menu-horiz{*zoom:1}.wy-menu-horiz:before,.wy-menu-horiz:after{display:table;content:""}.wy-menu-horiz:after{clear:both}.wy-menu-horiz ul,.wy-menu-horiz li{display:inline-block}.wy-menu-horiz li:hover{background:rgba(255,255,255,0.1)}.wy-menu-horiz li.divide-left{border-left:solid 1px #404040}.wy-menu-horiz li.divide-right{border-right:solid 1px #404040}.wy-menu-horiz a{height:32px;display:inline-block;line-height:32px;padding:0 16px}.wy-menu-vertical header{height:32px;display:inline-block;line-height:32px;padding:0 1.618em;display:block;font-weight:bold;text-transform:uppercase;font-size:80%;color:#2980b9;white-space:nowrap}.wy-menu-vertical ul{margin-bottom:0}.wy-menu-vertical li.divide-top{border-top:solid 1px #404040}.wy-menu-vertical li.divide-bottom{border-bottom:solid 1px #404040}.wy-menu-vertical li.current{background:#e3e3e3}.wy-menu-vertical li.current a{color:gray;border-right:solid 1px #c9c9c9;padding:0.4045em 2.427em}.wy-menu-vertical li.current a:hover{background:#d6d6d6}.wy-menu-vertical li.on a,.wy-menu-vertical li.current>a{color:#404040;padding:0.4045em 1.618em;font-weight:bold;position:relative;background:#fcfcfc;border:none;border-bottom:solid 1px #c9c9c9;border-top:solid 1px #c9c9c9;padding-left:1.618em -4px}.wy-menu-vertical li.on a:hover,.wy-menu-vertical li.current>a:hover{background:#fcfcfc}.wy-menu-vertical li.toctree-l2.current>a{background:#c9c9c9;padding:0.4045em 2.427em}.wy-menu-vertical li.current ul{display:block}.wy-menu-vertical li ul{margin-bottom:0;display:none}.wy-menu-vertical .local-toc li ul{display:block}.wy-menu-vertical li ul li a{margin-bottom:0;color:#b3b3b3;font-weight:normal}.wy-menu-vertical a{display:inline-block;line-height:18px;padding:0.4045em 1.618em;display:block;position:relative;font-size:90%;color:#b3b3b3}.wy-menu-vertical a:hover{background-color:#4e4a4a;cursor:pointer}.wy-menu-vertical a:active{background-color:#2980b9;cursor:pointer;color:#fff}.wy-side-nav-search{z-index:200;background-color:#2980b9;text-align:center;padding:0.809em;display:block;color:#fcfcfc;margin-bottom:0.809em}.wy-side-nav-search input[type=text]{width:100%;border-radius:50px;padding:6px 12px;border-color:#2472a4}.wy-side-nav-search img{display:block;margin:auto auto 0.809em auto;height:45px;width:45px;background-color:#2980b9;padding:5px;border-radius:100%}.wy-side-nav-search>a,.wy-side-nav-search .wy-dropdown>a{color:#fcfcfc;font-size:100%;font-weight:bold;display:inline-block;padding:4px 6px;margin-bottom:0.809em}.wy-side-nav-search>a:hover,.wy-side-nav-search .wy-dropdown>a:hover{background:rgba(255,255,255,0.1)}.wy-nav .wy-menu-vertical header{color:#2980b9}.wy-nav .wy-menu-vertical a{color:#b3b3b3}.wy-nav .wy-menu-vertical a:hover{background-color:#2980b9;color:#fff}[data-menu-wrap]{-webkit-transition:all 0.2s ease-in;-moz-transition:all 0.2s ease-in;transition:all 0.2s ease-in;position:absolute;opacity:1;width:100%;opacity:0}[data-menu-wrap].move-center{left:0;right:auto;opacity:1}[data-menu-wrap].move-left{right:auto;left:-100%;opacity:0}[data-menu-wrap].move-right{right:-100%;left:auto;opacity:0}.wy-body-for-nav{background:left repeat-y #fcfcfc;background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyRpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoTWFjaW50b3NoKSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDoxOERBMTRGRDBFMUUxMUUzODUwMkJCOThDMEVFNURFMCIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDoxOERBMTRGRTBFMUUxMUUzODUwMkJCOThDMEVFNURFMCI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOjE4REExNEZCMEUxRTExRTM4NTAyQkI5OEMwRUU1REUwIiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOjE4REExNEZDMEUxRTExRTM4NTAyQkI5OEMwRUU1REUwIi8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+EwrlwAAAAA5JREFUeNpiMDU0BAgwAAE2AJgB9BnaAAAAAElFTkSuQmCC);background-size:300px 1px}.wy-grid-for-nav{position:absolute;width:100%;height:100%}.wy-nav-side{position:absolute;top:0;left:0;width:300px;overflow:hidden;min-height:100%;background:#343131;z-index:200}.wy-nav-top{display:none;background:#2980b9;color:#fff;padding:0.4045em 0.809em;position:relative;line-height:50px;text-align:center;font-size:100%;*zoom:1}.wy-nav-top:before,.wy-nav-top:after{display:table;content:""}.wy-nav-top:after{clear:both}.wy-nav-top a{color:#fff;font-weight:bold}.wy-nav-top img{margin-right:12px;height:45px;width:45px;background-color:#2980b9;padding:5px;border-radius:100%}.wy-nav-top i{font-size:30px;float:left;cursor:pointer}.wy-nav-content-wrap{margin-left:300px;background:#fcfcfc;min-height:100%}.wy-nav-content{padding:1.618em 3.236em;height:100%;max-width:800px;margin:auto}.wy-body-mask{position:fixed;width:100%;height:100%;background:rgba(0,0,0,0.2);display:none;z-index:499}.wy-body-mask.on{display:block}footer{color:#999}footer p{margin-bottom:12px}.rst-footer-buttons{*zoom:1}.rst-footer-buttons:before,.rst-footer-buttons:after{display:table;content:""}.rst-footer-buttons:after{clear:both}#search-results .search li{margin-bottom:24px;border-bottom:solid 1px #e1e4e5;padding-bottom:24px}#search-results .search li:first-child{border-top:solid 1px #e1e4e5;padding-top:24px}#search-results .search li a{font-size:120%;margin-bottom:12px;display:inline-block}#search-results .context{color:gray;font-size:90%}@media screen and (max-width: 768px){.wy-body-for-nav{background:#fcfcfc}.wy-nav-top{display:block}.wy-nav-side{left:-300px}.wy-nav-side.shift{width:85%;left:0}.wy-nav-content-wrap{margin-left:0}.wy-nav-content-wrap .wy-nav-content{padding:1.618em}.wy-nav-content-wrap.shift{position:fixed;min-width:100%;left:85%;top:0;height:100%;overflow:hidden}}@media screen and (min-width: 1400px){.wy-nav-content-wrap{background:rgba(0,0,0,0.05)}.wy-nav-content{margin:0;background:#fcfcfc}}@media print{.wy-nav-side{display:none}.wy-nav-content-wrap{margin-left:0}}nav.stickynav{position:fixed;top:0}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;border-top:solid 10px #343131;font-family:"Lato","proxima-nova","Helvetica Neue",Arial,sans-serif;z-index:400}.rst-versions a{color:#2980b9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27ae60;*zoom:1}.rst-versions .rst-current-version:before,.rst-versions .rst-current-version:after{display:table;content:""}.rst-versions .rst-current-version:after{clear:both}.rst-versions .rst-current-version .icon,.rst-versions .rst-current-version .wy-inline-validate.wy-inline-validate-success .wy-input-context,.wy-inline-validate.wy-inline-validate-success .rst-versions .rst-current-version .wy-input-context,.rst-versions .rst-current-version .wy-inline-validate.wy-inline-validate-danger .wy-input-context,.wy-inline-validate.wy-inline-validate-danger .rst-versions .rst-current-version .wy-input-context,.rst-versions .rst-current-version .wy-inline-validate.wy-inline-validate-warning .wy-input-context,.wy-inline-validate.wy-inline-validate-warning .rst-versions .rst-current-version .wy-input-context,.rst-versions .rst-current-version .wy-inline-validate.wy-inline-validate-info .wy-input-context,.wy-inline-validate.wy-inline-validate-info .rst-versions .rst-current-version .wy-input-context,.rst-versions .rst-current-version .wy-tag-input-group .wy-tag .wy-tag-remove,.wy-tag-input-group .wy-tag .rst-versions .rst-current-version .wy-tag-remove,.rst-versions .rst-current-version .rst-content .admonition-title,.rst-content .rst-versions .rst-current-version .admonition-title,.rst-versions .rst-current-version .rst-content h1 .headerlink,.rst-content h1 .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content h2 .headerlink,.rst-content h2 .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content h3 .headerlink,.rst-content h3 .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content h4 .headerlink,.rst-content h4 .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content h5 .headerlink,.rst-content h5 .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content h6 .headerlink,.rst-content h6 .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content dl dt .headerlink,.rst-content dl dt .rst-versions .rst-current-version .headerlink{color:#fcfcfc}.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#e74c3c;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#f1c40f;color:#000}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:gray;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:solid 1px #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px}.rst-versions.rst-badge .icon-book{float:none}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge .rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width: 768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}img{width:100%;height:auto}}.rst-content img{max-width:100%;height:auto !important}.rst-content .section>img{margin-bottom:24px}.rst-content blockquote{margin-left:24px;line-height:24px;margin-bottom:24px}.rst-content .note .last,.rst-content .attention .last,.rst-content .caution .last,.rst-content .danger .last,.rst-content .error .last,.rst-content .hint .last,.rst-content .important .last,.rst-content .tip .last,.rst-content .warning .last,.rst-content .seealso .last{margin-bottom:0}.rst-content .admonition-title:before{margin-right:4px}.rst-content .admonition table{border-color:rgba(0,0,0,0.1)}.rst-content .admonition table td,.rst-content .admonition table th{background:transparent !important;border-color:rgba(0,0,0,0.1) !important}.rst-content .section ol.loweralpha,.rst-content .section ol.loweralpha li{list-style:lower-alpha}.rst-content .section ol.upperalpha,.rst-content .section ol.upperalpha li{list-style:upper-alpha}.rst-content .section ol p,.rst-content .section ul p{margin-bottom:12px}.rst-content .line-block{margin-left:24px}.rst-content .topic-title{font-weight:bold;margin-bottom:12px}.rst-content .toc-backref{color:#404040}.rst-content .align-right{float:right;margin:0px 0px 24px 24px}.rst-content .align-left{float:left;margin:0px 24px 24px 0px}.rst-content .align-center{margin:auto;display:block}.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content dl dt .headerlink{display:none;visibility:hidden;font-size:14px}.rst-content h1 .headerlink:after,.rst-content h2 .headerlink:after,.rst-content h3 .headerlink:after,.rst-content h4 .headerlink:after,.rst-content h5 .headerlink:after,.rst-content h6 .headerlink:after,.rst-content dl dt .headerlink:after{visibility:visible;content:"\f0c1";font-family:fontawesome-webfont;display:inline-block}.rst-content h1:hover .headerlink,.rst-content h2:hover .headerlink,.rst-content h3:hover .headerlink,.rst-content h4:hover .headerlink,.rst-content h5:hover .headerlink,.rst-content h6:hover .headerlink,.rst-content dl dt:hover .headerlink{display:inline-block}.rst-content .sidebar{float:right;width:40%;display:block;margin:0 0 24px 24px;padding:24px;background:#f3f6f6;border:solid 1px #e1e4e5}.rst-content .sidebar p,.rst-content .sidebar ul,.rst-content .sidebar dl{font-size:90%}.rst-content .sidebar .last{margin-bottom:0}.rst-content .sidebar .sidebar-title{display:block;font-family:"Roboto Slab","ff-tisa-web-pro","Georgia",Arial,sans-serif;font-weight:bold;background:#e1e4e5;padding:6px 12px;margin:-24px;margin-bottom:24px;font-size:100%}.rst-content .highlighted{background:#f1c40f;display:inline-block;font-weight:bold;padding:0 6px}.rst-content .footnote-reference,.rst-content .citation-reference{vertical-align:super;font-size:90%}.rst-content table.docutils.citation,.rst-content table.docutils.footnote{background:none;border:none;color:#999}.rst-content table.docutils.citation td,.rst-content table.docutils.citation tr,.rst-content table.docutils.footnote td,.rst-content table.docutils.footnote tr{border:none;background-color:transparent !important;white-space:normal}.rst-content table.docutils.citation td.label,.rst-content table.docutils.footnote td.label{padding-left:0;padding-right:0;vertical-align:top}.rst-content table.field-list{border:none}.rst-content table.field-list td{border:none;padding-top:5px}.rst-content table.field-list .field-name{padding-right:10px;text-align:left;white-space:nowrap}.rst-content table.field-list .field-body{text-align:left;padding-left:0}.rst-content tt{color:#000}.rst-content tt big,.rst-content tt em{font-size:100% !important;line-height:normal}.rst-content tt .xref,a .rst-content tt{font-weight:bold}.rst-content dl{margin-bottom:24px}.rst-content dl dt{font-weight:bold}.rst-content dl p,.rst-content dl table,.rst-content dl ul,.rst-content dl ol{margin-bottom:12px !important}.rst-content dl dd{margin:0 0 12px 24px}.rst-content dl:not(.docutils){margin-bottom:24px}.rst-content dl:not(.docutils) dt{display:inline-block;margin:6px 0;font-size:90%;line-height:normal;background:#e7f2fa;color:#2980b9;border-top:solid 3px #6ab0de;padding:6px;position:relative}.rst-content dl:not(.docutils) dt:before{color:#6ab0de}.rst-content dl:not(.docutils) dt .headerlink{color:#404040;font-size:100% !important}.rst-content dl:not(.docutils) dl dt{margin-bottom:6px;border:none;border-left:solid 3px #ccc;background:#f0f0f0;color:gray}.rst-content dl:not(.docutils) dl dt .headerlink{color:#404040;font-size:100% !important}.rst-content dl:not(.docutils) dt:first-child{margin-top:0}.rst-content dl:not(.docutils) tt{font-weight:bold}.rst-content dl:not(.docutils) tt.descname,.rst-content dl:not(.docutils) tt.descclassname{background-color:transparent;border:none;padding:0;font-size:100% !important}.rst-content dl:not(.docutils) tt.descname{font-weight:bold}.rst-content dl:not(.docutils) .optional{display:inline-block;padding:0 4px;color:#000;font-weight:bold}.rst-content dl:not(.docutils) .property{display:inline-block;padding-right:8px}.rst-content .viewcode-link,.rst-content .viewcode-back{display:inline-block;color:#27ae60;font-size:80%;padding-left:24px}.rst-content .viewcode-back{display:block;float:right}@media screen and (max-width: 480px){.rst-content .sidebar{width:100%}}span[id*='MathJax-Span']{color:#404040}.wy-menu-vertical span.toctree-l0{display:inline-block;line-height:18px;padding:0.4045em 1.318em;display:block;position:relative;font-size:80%;color:#838383}
\ No newline at end of file
This diff could not be displayed because it is too large.
<footer>
{% if next_page or previous_page %}
<div class="rst-footer-buttons" role="navigation" aria-label="footer navigation">
{% if next_page %}
<a href="{{ next_page.url }}" class="btn btn-neutral float-right" title="{{ next_page.title }}"/>Next <span class="icon icon-circle-arrow-right"></span></a>
{% endif %}
{% if previous_page %}
<a href="{{ previous_page.url }}" class="btn btn-neutral" title="{{ previous_page.title }}"><span class="icon icon-circle-arrow-left"></span> Previous</a>
{% endif %}
</div>
{% endif %}
<hr/>
<div role="contentinfo">
<p>
<!-- Copyright etc -->
</p>
</div>
Built with <a href="http://www.mkdocs.org">MkDocs</a>, using a <a href="https://github.com/snide/sphinx_rtd_theme">theme</a> provided by <a href="https://readthedocs.org">Read the Docs</a>.
</footer>
No preview for this file type
$( document ).ready(function() {
// Shift nav in mobile when clicking the menu.
$(document).on('click', "[data-toggle='wy-nav-top']", function() {
$("[data-toggle='wy-nav-shift']").toggleClass("shift");
$("[data-toggle='rst-versions']").toggleClass("shift");
});
// Close menu when you click a link.
$(document).on('click', ".wy-menu-vertical .current ul li a", function() {
$("[data-toggle='wy-nav-shift']").removeClass("shift");
$("[data-toggle='rst-versions']").toggleClass("shift");
});
$(document).on('click', "[data-toggle='rst-current-version']", function() {
$("[data-toggle='rst-versions']").toggleClass("shift-up");
});
// Make tables responsive
$("table.docutils:not(.field-list)").wrap("<div class='wy-table-responsive'></div>");
});
window.SphinxRtdTheme = (function (jquery) {
var stickyNav = (function () {
var navBar,
win,
stickyNavCssClass = 'stickynav',
applyStickNav = function () {
if (navBar.height() <= win.height()) {
navBar.addClass(stickyNavCssClass);
} else {
navBar.removeClass(stickyNavCssClass);
}
},
enable = function () {
applyStickNav();
win.on('resize', applyStickNav);
},
init = function () {
navBar = jquery('nav.wy-nav-side:first');
win = jquery(window);
};
jquery(init);
return {
enable : enable
};
}());
return {
StickyNav : stickyNav
};
}($));
{#
basic/search.html
~~~~~~~~~~~~~~~~~
Template for the search page.
:copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
#}
{%- extends "layout.html" %}
{% set title = _('Search') %}
{% set script_files = script_files + ['_static/searchtools.js'] %}
{% block extrahead %}
<script type="text/javascript">
jQuery(function() { Search.loadIndex("{{ pathto('searchindex.js', 1) }}"); });
</script>
{# this is used when loading the search index using $.ajax fails,
such as on Chrome for documents on localhost #}
<script type="text/javascript" id="searchindexloader"></script>
{{ super() }}
{% endblock %}
{% block body %}
<noscript>
<div id="fallback" class="admonition warning">
<p class="last">
{% trans %}Please activate JavaScript to enable the search
functionality.{% endtrans %}
</p>
</div>
</noscript>
{% if search_performed %}
<h2>{{ _('Search Results') }}</h2>
{% if not search_results %}
<p>{{ _('Your search did not match any documents. Please make sure that all words are spelled correctly and that you\'ve selected enough categories.') }}</p>
{% endif %}
{% endif %}
<div id="search-results">
{% if search_results %}
<ul>
{% for href, caption, context in search_results %}
<li>
<a href="{{ pathto(item.href) }}">{{ caption }}</a>
<p class="context">{{ context|e }}</p>
</li>
{% endfor %}
</ul>
{% endif %}
</div>
{% endblock %}
<div role="search">
<form id ="rtd-search-form" class="wy-form" action="" method="get">
<input type="text" name="q" placeholder="Search docs" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
<ul class="current">
{% for nav_item in nav %}
{% if nav_item.children %}
<span class="toctree-l0">{{ nav_item.title }}</span>
{% for nav_item in nav_item.children %}
<li class="toctree-l1 {% if nav_item.active%}current{%endif%}">
<a class="{% if nav_item.active%}current{%endif%}" href="{{ nav_item.url }}">{{ nav_item.title }}</a>
{% if nav_item == current_page %}
<ul>
{% for toc_item in toc %}
<li class="toctree-l2"><a href="{{ toc_item.url }}">{{ toc_item.title }}</a></li>
{% for toc_item in toc_item.children %}
<li><a class="toctree-l3" href="{{ toc_item.url }}">{{ toc_item.title }}</a></li>
{% endfor %}
{% endfor %}
</ul>
{% endif %}
</li>
{% endfor %}
{% else %}
<li class="toctree-l1 {% if nav_item.active%}current{%endif%}">
<a class="{% if nav_item.active%}current{%endif%}" href="{{ nav_item.url }}">{{ nav_item.title }}</a>
</li>
{% endif %}
{% endfor %}
</ul>
git+https://github.com/dart-lang/py-gfm.git
site_name: Sequelize - node.js ORM for Postgres, MySQl, MariaDB and SQLite
theme_dir: docs/readthedocs_theme
repo_url: https://github.com/sequelize/sequelize
site_favicon: favicon.ico
markdown_extensions: [gfm]
extra_css:
- css/custom.css
extra_javascript:
- //cdnjs.cloudflare.com/ajax/libs/highlight.js/8.4/highlight.min.js
pages:
- ['index.md', 'Home', 'Welcome']
- ['imprint.md', 'Home', 'Imprint']
- ['articles/getting-started.md', 'Articles', 'Getting started']
- ['articles/heroku.md', 'Articles', 'Heroku']
- ['articles/express.md', 'Articles', 'Usage with Express.JS']
- ['docs/installation.md', 'Docs', 'Installation']
- ['docs/usage.md', 'Docs', 'Usage']
- ['docs/promises.md', 'Docs', 'Promises']
- ['docs/models.md', 'Docs', 'Models']
- ['docs/instances.md', 'Docs', 'Instances']
- ['docs/associations.md', 'Docs', 'Associations']
- ['docs/hooks.md', 'Docs', 'Hooks']
- ['docs/transactions.md', 'Docs', 'Transactions']
- ['docs/migrations.md', 'Docs', 'Migrations']
- ['docs/misc.md', 'Docs', 'Misc']
- ['api/sequelize.md', 'API', 'Sequelize']
- ['api/model.md', 'API', 'Model']
- ['api/instance.md', 'API', 'Instance']
- ['api/associations.md', 'API', 'Associations']
- ['api/hooks.md', 'API', 'Hooks']
- ['api/promise.md', 'API', 'Promise']
- ['api/transaction.md', 'API', 'Transaction']
- ['api/datatypes.md', 'API', 'Datatypes']
- ['api/errors.md', 'API', 'Errors']
......@@ -76,7 +76,8 @@
"main": "index",
"scripts": {
"test": "make all",
"docs": "node_modules/.bin/yuidoc . -o docs"
"docs": "node docs/docs-generator.js",
"prepublish": "docs"
},
"engines": {
"node": ">=0.6.21"
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!